204°

JVM虚拟机堆的垃圾回收机制

堆内存中,分为年轻代,老年代。

new出来的对象,放在堆内存中,具体会放到eden区。

当堆的内存设置为600M时,老年代会占400M内存,年轻代会占200M。而eden区,会占160M内存,整个survivor区占40M。

当程序一直在运行,eden区被占满时,java虚拟机(后台)会执行一个minor gc(也叫young gc)线程,对eden区来执行垃圾收集。

可达性分析算法

GC线程在eden区收集垃圾,会用到可达性分析算法。

将“GC ROOTS”对象作为起点,从这些节点开始向下搜索引用的对象,找到的对象都标记为非垃圾对象,其余未标记的对象都是垃圾对象。

GC Roots根节点:线程栈的本地变量、类方法区中的静态变量、线程栈的本地方法栈的变量等。

GC线程,顺着GC Roots一步一步往下找,能找到的对象,都是有效对象,都会被转移到survivor区域,eden区剩下的对象就是垃圾对象。

 

对象头:

每个对象,都内存中,都存着自己的对象头信息。

对象的信息头中,会标识它,每经历过一次minor gc,分代年龄就会加一。

第一次做minor gc的时候,会清理eden区域,将非垃圾对象,转移到survivor的From区域中,这些对象在对象头中,会增加自己的分代年龄。

当eden区再次满了之后,gc不但会清理eden区的对象,也会清理这些上次被清理过,已经转移到survivor的From区域中的对象。因为经过一段时间后,这些对象可能会变成垃圾。经过本次minor gc后,还不是垃圾对象的,会进过复制算法,转移到survivor的To内存区域,并且对象的对象头中,分代年龄各自加一。

当eden区再次满了之后,gc又会清理eden区域和Survivor中To区域的对象。并将存活的对象,转移到Survivor的From区域,并增加分代年龄。

所以,活着的对象,会在年轻代survivor内存区域中被挪来挪去。每挪一次,对象的分代年龄就会加一,等对象的分代年龄加到15,就会把该对象挪到老年代内存区域。

当随着程序运行越来越久,挪到老年代的对象越来越多,老年代的内存也会满。老年代的内存满了之后,会启动full gc  ,它会对所有的堆进行垃圾收集,包括老年代和年轻代。

 

 

问题:

survivor内存区域的From和To内存区满了怎么办?

本文由【太猪-YJ】发布于开源中国,原文链接:https://my.oschina.net/xiaoyoung/blog/3157821

全部评论: 0

    我有话说: