zoukankan      html  css  js  c++  java
  • 2,理解JVM

     
    一、内存管理:
     
    1,内存结构:
    栈和堆区别,栈是连续内存区,一般是2M单位,堆是不连续的链表。受限于虚拟内存,new时分配
    PC寄存器、java栈、堆、方法区、本地方法区、运行常量池
    java栈:对应一个线程,每个栈中的栈帧关联每个方法,运行一个方法创建一个栈帧,执行完就弹出栈帧。不是线程共享,不用关心数据一致性和同步锁这些线程问题。
    :程序猿最关心的,是new对象和对象数组时创建的,所有线程共享,保证一致性。
    方法区:储存类结构信息,比如class文件解析后,常量池,方法数据,方法体,构造函数,实例初始化等储存在这里。
    常量区:每个class文件的常量表,是方法区的一部分。即和方法区的常量池是一回事。
    本地方法栈,为运行Native方法准备的,类似java栈。
     
     
    2,内存分配策略:
    静态分配: 程序编译和连接的时候,不允许有可变数据结构如可变数组,也不允许嵌套或递归。 C语言,源文件大小,和编译生成另外一个大小
    栈内存分配:程序对数据区编译时是未知的,运行时才知道,但规定进入一个程序模块时,必须知道所需的数据区大小。也是先进后出的栈
    堆分配:运行到相应代码时才会知道空间大小。
     
    3,java内存分配:
    堆和栈
    栈一般不关心,是对应到线程的。速度比对快,仅次于寄存器。栈帧的数据大小和生存期必须确定,缺乏灵活性。
    堆,程序猿最要关心的,每个java应用对应唯一JVM实例,每个实例唯一对应一个堆。当然由这个应用的所有线程共享。由于垃圾回收GC来释放。
    通俗的说,栈来执行程序,一个栈对应一个线程,堆来存放对象。堆要请求操作系统来分配内存,所以分配和销毁都需要时间,所以效率低。优点是灵活可变。
     
    二、内存回收
     
    1,静态内存回收
    自动的,方法结束,对应的栈帧也就撤销。
     
    2,动态内存回收
    对象是否被使用,何时回收。
    不被引用的对象,即不可达。这些对象会被回收
     
    内存泄露就是被引用了,可达的。但是无用的,程序不用使用它们。不被GC回收,占内存浪费。
     
    三、基于分代GC算法
     
    分几组,年轻和年老的,几次回收后还存活,就放到年老组,年老组手机频度不那么高。
    对不同的区使用不同收集算法。
    1,串行
    在client模式下默认,单线程完成,JVM其他应用被暂停。
    适合内存有限,回收慢
     
    2,并行
    在server模式下默认,多线程,其它应用也被暂停。
    效率高,堆过大时,暂停时间长
     
    3,并发
    并发数默认为4
    old区暂停时间段,但产生内存碎片,耗CPU

    4,G1收集器

    G1是目前垃圾收集技术发展的最新成果之一,它与前面的几款GC最大的不同在于:
     
    G1可管理整个堆区,包括新生代和老年代。G1在物理上不区分新生代和老年代。G1会把整个堆划分为很多区域(Region),新生代和老年代现在变更了仅仅是逻辑上的概念,它们并不需要在物理上严格区分。G1会对所有Region进行回收效率排序,优先清理回收效率最高的Region
    除此之外,G1与CMS也是并发执行的GC,即执行清理时可以与用户线程同时(并发)执行,但是G1可以做到比CMS更短暂的停顿时间
     
     
    GC组合实践:Server模式下的HotSpot JVM
    为新生代和老年代指定不同的GC
    1,老年代用并发
    2,-XX:UseG1GC  全部用G1GC
     
    -Xms是设置内存初始化的大小
    -Xmx是设置最大能够使用内存的大小
     
    设置方法:
    1,eclipse可以设置VM参数 对在当前开发环境中运行的java程序皆生效
    编辑当前使用的JRE,在缺省VM参数中输入:
     
    2,tomcat,对tomcat下的应用程序生效
    打开Tomcat根目录下的bin文件夹,编辑catalina.bat,在setJAVA_OPTS=%JAVA_OPTS%....这句之后加上:setJAVA_OPTS=%JAVA_OPTS%-Xms1024m-Xmx1024m
     
    四、内存泄露
     
    就是被引用了,可达的。但是无用的,程序不用使用它们。不被GC回收,占内存浪费。
    如何检测JVM内存泄漏
    如何检测Java的JVM内存泄漏。目前,我们通常使用一些工具来检查Java程序的JVM内存泄漏问题。市场上已有几种专业检查JavaJVM内存泄漏的工具,它们的基本工作原理大同小异,
    都是通过监测Java程序运行时,所有对象的申请、释放等动作,将内存管理的所有信息进行统计、分析、可视化
     
    五、写代码时要注意的内存泄露
     
    0,单例+对象池是个好习惯,无论数据库连接池、http连接池,还是redis,MQ消息队列。可以说单例+对象池是性能优化的万能灵药,减少了资源占用,提升了效率。
    1,避免使用Vector,对象放入一个Vector中,如果我们仅仅释放引用本身,那么Vector仍然引用该对象。也要注意List、MAP
    2,小心内部类,如果内部类被引用了。导致整个对象被引用,实际上整个对象可能用不到。
    3,注意代码中死循环或递归调用 
    由于我是C#转来的,Vector和内部类不在我的食谱中无需考虑。
    3,Js也要小心内存泄露。同样小心循环引用,对于后台人员写JS,这不是问题
     
     
     
  • 相关阅读:
    不叹惜、不呼唤我也不哭泣
    WCF笔记(一)Service Layer and Channel Layer
    C#数据结构(四)树和二叉树
    Python and django(四)详解python中的数字和序列
    Python and django(三)python中的对象
    IIS与ASP.NET Http Runtime Pipeline
    迈进程序员的大门
    实例学习SSIS(四)使用日志记录和错误流重定向
    DbUtility alpha1版本发布
    关于ref和out的详细区别。
  • 原文地址:https://www.cnblogs.com/zkp2010/p/5510459.html
Copyright © 2011-2022 走看看