前言:
此时兄弟们对“jvm回收机制原理”可能比较讲究,兄弟们都想要分析一些“jvm回收机制原理”的相关知识。那么小编同时在网络上汇集了一些关于“jvm回收机制原理””的相关资讯,希望同学们能喜欢,你们一起来了解一下吧!上节我们讲解了JVM中有哪些垃圾回收算法,每个算法各自的优势及它们之间的区别
本节继续讲解JVM垃圾回收原理
那什么情况下JVM内存中的一个对象会被垃圾回收?
如果新生代或老年代里的对象越来越多,都快满了,此时就会触发垃圾回收,把新生代及新生代中没有人引用的对象给回收掉,释放内存空间。
被哪些变量引用的对象是不能回收的?
JVM中使用了一种可达性分析算法来判定哪些对象是可以被回收的,哪些对象是不可以被回收的。这个算法的意思,就是说对每个对象,都分析一下有谁在引用他,然后一层一层往上去判断,看是否有一个GC Roots,有GC Roots引用的对象不能回收,没有GC Roots引用的对象可以回收,如果有GC Roots引用,但是如果是软引用或者弱引用的,也有可能被回收掉。在JVM规范中,方法的局部变量就是可以作为GC Roots,静态变量也可以看做是一种GC Roots。
复制算法的优化:Eden区和Survivor区
由于复制算法把新生代分为两块相同区域,新生代用的垃圾回收过后,99%的对象其实都被垃圾回收了,就1%的对象存活了下来,可能就是一些长期存活的对象,或者还没使用完的对象。所以为避免空间浪费,实际上真正的复制算法会做出如下优化,把新生代内存区域划分为三块:
1个Eden区,2个Survivor区(分别叫from和to)。
默认比例为8:1其中Eden区占80%内存空间,每一块Survivor区各占10%内存空间,比如说Eden区有800MB内存,每一块Survivor区就100MB内存,如下图:
如果说Eden区域满了,此时必然触发垃圾回收(Minor GC/young GC/YGC)
垃圾回收的时候有一个概念,叫做stop the world,停止你的jvm里的工作线程的运行,然后扫描所有的对象,判断哪些可以回收,哪些不可以回收的。
一般情况下,新创建的对象都会被分配到Eden区(一些大对象特殊处理),如果Eden区满了,会进行Minor GC,这些对象经过第一次Minor GC后,如果仍然存活,将会被移到Survivor区。对象在Survivor区中每熬过一次Minor GC,年龄就会增加1岁,当它的年龄增加到一定阈值(默认阈值15岁,可配置)时,就会被移动到年老代中。
对象进入老年代的条件有很多,后面我们会进行讲解。
因为年轻代中的对象基本都是朝生夕死的(80%以上),所以在年轻代的垃圾回收算法使用的是复制算法,复制算法不会产生内存碎片。
在GC开始时,对象只存在于Eden区和"From"区,"To"区是空的。紧接着进行GC,Eden区中所有存活的对象都会被复制到"To",而在"From"区中,仍存活的对象会根据他们的年龄值来决定去向。年龄达到一定阈值的对象会被移动到年老代中,没有达到的对象会被复制到"To"区域。经过这次GC后,Eden区和From区已经被清空。这个时候,"From"和"To"会交换他们的角色,也就是新的"To"就是上次GC前的"From",新的"From"就是上次GC前的"To"。不管怎样,都会保证名为To的Survivor区域是空的。Minor GC会一直重复这样的过程,直到"To"区被填满,"To"区被填满之后,会将所有对象移动到年老代中。
对象是达到年龄的就进入老年代中去的吗?是不是只有To区填满后才会进入年老代中去呢?
下节讲解进入老年代规则。
标签: #jvm回收机制原理