近期由于jvm经常出现full gc导致jvm崩溃,从日志上查看是Eden和survivor from,to相关的信息,经学习了相关文档和文章后,特总结如下。
参照并发编程网中的讲解,特有以下的记录。ref :http://ifeve.com/jvm-yong-generation/
对象生命story
对一个新的东西的理解,最好不要一上来就看各种原理,最好是有个恰当的故事strory开始,有助于我们理解之后的事情。
好了,故事开始:我是一个普通的java对象,上帝将我降生在Eden区,在这个区里有和我一起成长的兄弟,我们在Eden区玩了很长一段时间,渐渐的这个区里的人接近饱和了,某一天上帝清点了人数,我就被迫去了Survivor区中的from区,自从到了from区,我就从from区到to区来回漂泊,居无定所。直到我18岁时,上帝告知我已成人,可以到社会上去闯闯,于是我到了Tenured代(老年代),在这里人很多,并且大家年龄都挺大的,我在Tenured存在了很久,直到很多年后,上帝找到我,将我回收...
围绕这个故事,对于jvm内存,gc,及gc算法大概就发生在这个故事里。
年轻代 年老代 永久代
jvm中大概能划分为以下3个代
Yong generation ->年轻代,新生代 :所有新生成的对象首先会被放在此区,这个区的设计是回收那些生命周期短的对象。此区域分为3个区,Eden,survivor区中的from和to区
Tenured/Old generation -->年老代:经历了多次垃圾回收后还存活的对象,会被放入此区。
Perm Area 永久代,方法区 :存放静态文件,如类,方法。存储每个类的结构信息,比如运行时常量池,字段和方法数据。
各区参数相关参数配置
-xms,-xmx 指定堆内存的初始大小和最大内存大小,为了gc回收时不压缩堆内存,一般的配置这两个值相等。
-XX:NewSize和-XX:MaxNewSize 指定年轻代的初始大小和最大,一般设置成样大,并且大小为堆内存的1/3或1/4
-XX:NewRatio 年老代与年轻代的比值,eg=2,则年老代占用2/3,年轻代占用1/3
-XX:SurvivorRatio Eden区与survivor区的比值(survivor=from+to)默认为8,即eden占用年轻代的8/10,from和to各占用1/10
-XX:PermSize,-XX:MaxPermSize 永久代初始与最大大小,建议为物理内存的1/64和1/4 该配置在jdk8之后废弃,采用MetaSpace
-XX:PrintTenuringDistribution 用于显示在每次Minor GC后,新的各区的阀值
最后,由于程序运行时,导致Eden中频繁创建对象,从开始的eden到from,to之间,再到年老代。由于计算巨大,变量生命周期长,导致full gc不能回收对象,最后抛出Heap outofmemory exception...
当eden区满时,jvm会释放eden区中不活跃的对象,如果空间仍然不够,则将部分活跃的对象移至survivor区(survivor区满不能触发gc),当年老代有足够空间,则将survivor中的对象移动到此,慢慢的如果年老代空间达到gc条件,则触发一次Major collection。
关于gc回收算法,在另一篇笔记中详解...
网友评论