电脑故障

位置:IT落伍者 >> 电脑故障 >> 浏览文章

GC策略&内存申请、对象衰老


发布日期:2020/8/28
 

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

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

young generation有eden个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都将内存中所有对象都检查一遍

非堆内存不GC

GC不会在主程序运行期对PermGen Space进行清理所以如果你的应用中有很多CLASS(特别是动态生成类当然permgen space存放的内容不仅限于类)的话就很可能出现PermGen Space错误

内存申请对象衰老过程

内存申请过程

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

&#;当Eden空间足够时内存申请结束否则到下一步

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

&#;Survivor区被用来作为Eden及old的中间交换区域当OLD区空间足够时Survivor区的对象会被移到Old区否则会被保留在Survivor区

&#;当old区空间不够时JVM会在old区进行major collection

&#;完全垃圾收集后若Survivor及old区仍然无法存放从Eden复制过来的部分对象导致JVM无法在Eden区为新对象创建内存区域则出现Out of memory错误

对象衰老过程

&#;新创建的对象的内存都分配自edenMinor collection的过程就是将eden和在用survivor space中的活对象copy到空闲survivor space中对象在young generation里经历了一定次数(可以通过参数配置)的minor collection后就会被移到old generation中称为tenuring

&#;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空间不足

显示调用SystemGC 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错误

上一篇:Groovy on rails使用

下一篇:Sender ID框架规范概述