深入理解JVM读后总结。
深入理解JVM(二)
垃圾回收机制(GC)
GC根据发生区域的不同分为两种:Minor GC
和Full GC
。
- Minor GC:指发生在新生代的垃圾回收,回收速度快,发生次数频繁;
- Full GC:指发生在老年代的GC,速度很慢,应尽量避免
大多数情况下,对象在eden区
中分配,若eden区内存不足,虚拟机会发起一次Minor GC。
如何判断对象需要回收?
引用计数法
给对象添加一个引用计数器,每当对象有一个地方引用它,计数器的值就加1,当引用失效时,计数器的值就减1,任何时刻计数器为0的对象就无法被使用了。
- 引用计数器的弊端是它很难解决对象之间相互循环引用的问题,当对象A和B互相引用时,它们无法再被访问,但次数引用计数器都不为0,所以无法回收。
可达性分析算法
目前JVM的主流方式都是采用可达性分析算法,核心思想是从GC Roots
节点开始向下搜索,当一个对象到GC Root之间没有任何引用链时,该对象是不可用的。
关于引用
分为强引用、软引用、弱引用和虚引用。
软引用和弱引用的区别?
软引用关联的对象,在系统将要发生内存溢出之前,将会把这些对象列进回收范围内。而被弱引用关联的对象只能生存到下一次垃圾收集发生之前,即哪怕内存足够,只要被GC扫描到就会被回收。
finalize()
要真正宣告一个对象死亡,至少要经历两次标记过程:
- 对象与GC Roots没有引用链相连时,会被第一次标记并进行一次筛选,筛选的依据是对象是否有必要执行
finalize()
方法。对象没有覆盖finalize()时,finalize()已经被jvm调用过时,都没有必要执行。有必要执行的对象会放在F-Queue
队列中。 - GC会对F-Queue中的对象进行第二次标记,如果对象要在finalize()中拯救自己,只要建立起与其他有引用链对象之间的引用链即可。
tips:
- 对象若自救成功,则第二次自救必定失败,因为finalize()只会被调用一次;
- 尽量避免使用finalize(),使用try-finally替代。
垃圾收集算法
标记-清除算法
主要不足:
- 标记和清除操作的效率都不高;
- 空间问题,清除后会产生大量不连续的内存碎片。