JVM系列二:GC策略&内存申请、对象衰老

JVM里的GC(Garbage Collection)的算法有不少种,如标记清除收集器,压缩收集器,分代收集器等等,详见HotSpot VM GC 的种类html

       如今比较经常使用的是分代收集(generational collection,也是SUN VM使用的,J2SE1.2以后引入),即将内存分为几个区域,将不一样生命周期的对象放在不一样区域里:young generationtenured generation和permanet generation。绝大部分的objec被分配在young generation(生命周期短),而且大部分的object在这里die。当young generation满了以后,将引起minor collection(YGC)。在minor collection后存活的object会被移动到tenured generation(生命周期比较长)。最后,tenured generation满以后触发major collection。major collection(Full gc)会触发整个heap的回收,包括回收young generation。permanet generation区域比较稳定,主要存放classloader信息。java

       young generation有eden、2个survivor 区域组成。其中一个survivor区域一直是空的,是eden区域和另外一个survivor区域在下一次copy collection后活着的objecy的目的地。object在survivo区域被复制直到转移到tenured区。算法

       咱们要尽可能减小 Full gc 的次数(tenured generation 通常比较大,收集的时间较长,频繁的Full gc会致使应用的性能收到严重的影响)。多线程

堆内存GC
       JVM(采用分代回收的策略),用较高的频率对年轻的对象(young generation)进行YGC,而对老对象(tenured generation)较少(tenured generation 满了后才进行)进行Full GC。这样就不须要每次GC都将内存中全部对象都检查一遍。性能

非堆内存不GCspa

      GC不会在主程序运行期对PermGen Space进行清理,因此若是你的应用中有不少CLASS(特别是动态生成类,固然permgen space存放的内容不只限于类)的话,就极可能出现PermGen Space错误。线程

内存申请、对象衰老过程
1、内存申请过程orm

  1. JVM会试图为相关Java对象在Eden中初始化一块内存区域;htm

  2. 当Eden空间足够时,内存申请结束。不然到下一步;对象

  3. JVM试图释放在Eden中全部不活跃的对象(minor collection),释放后若Eden空间仍然不足以放入新对象,则试图将部分Eden中活跃对象放入Survivor区;

  4. Survivor区被用来做为Eden及old的中间交换区域,当OLD区空间足够时,Survivor区的对象会被移到Old区,不然会被保留在Survivor区;

  5. 当old区空间不够时,JVM会在old区进行major collection;

  6. 彻底垃圾收集后,若Survivor及old区仍然没法存放从Eden复制过来的部分对象,致使JVM没法在Eden区为新对象建立内存区域,则出现"Out of memory错误";

2、对象衰老过程

  1. 新建立的对象的内存都分配自eden。Minor collection的过程就是将eden和在用survivor space中的活对象copy到空闲survivor space中。对象在young generation里经历了必定次数(能够经过参数配置)的minor collection后,就会被移到old generation中,称为tenuring。

  2. GC触发条件

    GC类型 触发条件 触发时发生了什么 注意 查看方式
    YGC eden空间不足

    清空Eden+from survivor中全部no ref的对象占用的内存
    将eden+from sur中全部存活的对象copy到to sur中
    一些对象将晋升到old中:
        to sur放不下的
        存活次数超过turning threshold中的
    从新计算tenuring threshold(serial parallel GC会触发此项)

    从新调整Eden 和from的大小(parallel GC会触发此项)

    全过程暂停应用
    是否为多线程处理由具体的GC决定
    jstat –gcutil 
    gc log
    FGC

    old空间不足
    perm空间不足
    显示调用System.GC, RMI等的定时触发
    YGC时的悲观策略
    dump live的内存信息时(jmap –dump:live)

    清空heap中no ref的对象
    permgen中已经被卸载的classloader中加载的class信息

    如配置了CollectGenOFirst,则先触发YGC(针对serial GC)
    如配置了ScavengeBeforeFullGC,则先触发YGC(针对serial GC)

    全过程暂停应用
    是否为多线程处理由具体的GC决定

    是否压缩须要看配置的具体GC
    jstat –gcutil 
    gc log

    permanent generation空间不足会引起Full GC,仍然不够会引起PermGen Space错误。

参考:

http://jiangyongyuan.javaeye.com/blog/356502

http://www.helloying.com/blog/archives/164

相关文章
相关标签/搜索