垃圾收集器与内存分配策略

编程

对象已死?

垃圾标记算法

1.引用计数算法

C++智能指针、Python

2.可达性分析算法

Java

GC Roots的根对象作为起始节点,通过引用链到某个对象不可达时,证明此对象不可能再被使用。


强引用:

通常所见的引用

软引用:

描述一些还有用,但非必须的对象。系统将要发生内存溢出异常前,对软引用对象进行二次回收,仍然没有足够内存才会抛出异常。

弱引用:

只能生存到下一次垃圾收集发生为止。无论内存是否足够。

虚引用:

无法通过虚引用获得对象实例,为对象设置虚引用的目的只是为了在对象被回收时收到系统通知。


回收一个对象必须经过至少两次标记过程:

1.可达性分析后没有与GC Roots相连接的引用链,那会被第一次标记。

2.根据finalize()是否有必要执行(finalize()方法只能被执行一次,第二次将判定为没必要执行),将对象放入F-Queue中,由虚拟机建立的Finalizer线程去执行他们的finalize()方法。只要重新与引用链上的对象建立关联,则不会被收集,否则就要被回收。

不要使用finalize(),任何事可以由try-finally来做。


回收方法区

-Xnoclassgc

在大量使用反射、动态代理、CGLib等字节码框架的场景,需要jvm具备类型卸载的能力,保证不会对方法区造成过大的内存压力。


垃圾收集算法

分为两种:

  • 引用计数式垃圾收集(直接垃圾收集)
  • 追踪式垃圾收集(间接垃圾收集) Java

标记-清除算法

标记过程即为上述垃圾标记算法,清除被标记的对象,反之亦可。

缺点:

  1. 执行效率不稳定
  2. 产生大量不连续内存碎片

标记-复制算法

内存分成两部分,标记清除后剩余的对象,复制到另一个部分,使得解决内存碎片的问题。

缺点:

  1. 对象复制成本高
  2. 可用内存缩小为原来的一半

标记-整理算法

将所有存活的对象往内存另一侧移动,然后直接清理掉边界以外的内存。

缺点:

对于老年代对象来说,有大量对象存活区域,移动对象必须暂停用户应用线程。

从JDK 12的ZGC技术实现了整理过程与用户线程并发执行。

Appel式回收算法

一种比标记-复制算法更优的半区复制分代策略,把内存分为Eden区和两块Survivor区,默认比例是8:1:1。


HotSpot算法实现细节

安全点

要求必须执行到安全点才能够暂停,进行垃圾收集。安全点得选择基本是以 `是否具有让程序长时间执行的特征`,如方法调用,循环跳转,异常跳转。

当垃圾收集发生时,让所有线程跑到最近的安全点停下来,有两种方案:

1.抢占式中断(几乎没有虚拟机实现)

2.主动式中断

未完...


参考:《深入理解Java虚拟机》 第3版 周志明

以上是 垃圾收集器与内存分配策略 的全部内容, 来源链接: utcz.com/z/516920.html

回到顶部