JVM垃圾回收
初学JVM,对自己的学习进行记录。
参考:JavaGuide .
《深入理解Java虚拟机 第二版》
1. JVM内存的分配与回收
java的自动内存管理主要是针对对象的内存分配与回收。java堆是GC的主要场所,所以java堆也被称为GC堆。从垃圾回收的角度来讲,现在的垃圾收集器基本是采用分代收集,所以堆还能分为新生代(Eden 空间、From Survivor、To Survivor 空间)和老年代(tentired )。
1.1 对象优先在Eden分配
大多数情况下,对象在新生代中 eden 区分配。当 eden 区没有足够空间进行分配时,虚拟机将发起一次 Minor GC。
1.2 大对象直接进入老年代
为了避免为大对象分配内存时由于分配担保机制带来的复制而降低效率。
1.3 长期存活的对象将进入老年代
如果对象在 Eden 出生并经过第一次 Minor GC 后仍然能够存活,并且能被 Survivor 容纳的话,将被移动到 Survivor 空间中,并将对象年龄设为 1.对象在 Survivor 中每熬过一次 MinorGC,年龄就增加 1 岁,当它的年龄增加到一定程度(默认为 15 岁),就会被晋升到老年代中。对象晋升到老年代的年龄阈值,可以通过参数 -XX:MaxTenuringThreshold 来设置。
1.4 动态对象年龄判断
Hotspot遍历所有对象时,按照年龄从小到大对其所占用的大小进行累积,当累积的某个年龄大小超过了survivor区的一半时,取这个年龄和MaxTenuringThreshold中更小的一个值,作为新的晋升年龄阈值
2.对象已死吗?
几乎所有的对象实例都存放在堆中,而垃圾回收的第一步,就是判断那些对象需要回收。
2.1 引用计数法
给对象中添加一个引用计数器,每当有一个地方引用它,计数器就加 1;当引用失效,计数器就减 1;任何时候计数器为 0 的对象就是不可能再被使用的。
这个方法实现简单,效率高。但是它很难解决对象之间相互循环引用的问题:除了对象 A 和 B 相互引用着对方之外,这两个对象之间再无任何引用。但是他们因为互相引用对方,导致它们的引用计数器都不为 0,于是引用计数算法无法通知 GC 回