垃圾回收策略

312 阅读4分钟
  • Java中的引用:
    • 强引用:

Object o=new Object(),只要引用还在不进行回收

    • 软引用:

内存溢出之前,进行第二次回收会回收这部分对象,内存还不足,会抛出异常, SoftReference。

    • 弱引用:

弱于软引用,下一次垃圾回收会回收该类型的对象。WeakReference

    • 虚引用:

最弱的一种, 又称幽灵或幻影引用,不影响对象的生存,但是被引用对象被回收时会有通知,PhantomReference。

  • 如何判断对象已死?
  1. 引用计数法,(JVM未使用,不能屏蔽相互引用的方式)
  2. 可达性分析,以一系列“GC Root”作为起点,找到不连通的节点判断为对象已死。
  • 最后一次存活的机会finalize
    • 对象被标记一次,后需要判断是否需要执行finalize方法。
    • 若对象未覆盖finalize方法,对应已执行过finalize方法,则不执行finalize。

否则需要执行,对象会放到F-Queue队列中,有虚拟机创建的Finalizer(低优先级)

线程触发对象的finalize方法。不承诺会等待他结束。防止系统卡死回收时造成系统崩溃。

    • 不建议覆盖finalize方法。
  • 永久代的垃圾回收
    • 方法区回收的性价比低
    • 永久代垃圾回收主要两部分:废弃常量和无用类
    • 判断一个无用类的条件如下:
  1. 该类所有的实例都已经被回收,也就是Java堆中不存在该类的实例
  2. 该类的ClassLoader已被回收
  3. 该类对应的java.lang.Class没有任何地方被引用。即没有任何地方通过范式访问该类。
      • 相关参数:

-Xnoclassgc,关闭类回收

-verbose:class (显示类详细信息)和

-XX+TraceClassLoading(跟踪类加载信息) 需要Product版本JVM

-XX+TraceClassUnLoading(跟踪类卸载信息) 需要FastDebug版本JVM

    • 大量使用反射,动态代理,CGLib的框架需要虚拟机开启类卸载功能,防止永久待溢出。
  • 垃圾回收算法

    • 标记-清除算法,没有使用,缺点:大对象无法找到连续的内存,触发GC
    • 复制算法:新生代标准算法,Eden:Survivor=8:1 ,1块Eden(80%)和2块Surivor(from(10%),to(10%)),预计只有10%作为预留空间。

回收时,将存活对象拷贝到预留的Survivor中,之后清除已使用的Eden和Survivor。

预留Surivor不够时,需要老年代进行分配担保。

    • 标记整理:标记后,将所有存活对象向一端移动,之后清除边界外的对象。(老年代算法)
    • 分代算法,整合上述算法,将JVM分成,新生代和老年代,新生代使用复制算法,老年代使用标记-清除 或标记整理算法。
  • HotSpot算法实现细节
    • 枚举根节点
  1. 必须暂停所有线程(Stop the world),目前JVM都是准确式GC,即可以准确知道那些地方存放着对象的引用。
  2. HotSpot通过OopMap实现。类加载完成把类内部什么偏移量是什么类型数据计算出来,

在JIT编译过程中会在特定的位置记录下栈和寄存器中那些位置的引用。

    • 安全点(解决程序执行时进入GC的问题)

造成OopMap的内容变化的指令非常多,JVM并未对每条指令都记录OopMap,以避免过多的内存占用。

JVM只在“特定的位置”记录OopMap,这些位置被称为安全点。只有到达安全点才能暂停开始GC。

安全点的选择以“是否让程序长时间执行的特征”为标准进行选定。

(最明显的是指令复用)例如:方法调用,循环跳转,异常跳转等。

      • 线程如何到达安全点,抢占式,主动式。
  1. 抢占式,没有JVM使用,在GC发生时,首先中断所有线程,若有线程未到安全点,就恢复线程,让“它”跑到安全点。
  2. 主动式,简单的设置一个标志,各个线程执行时主动去轮询这个标志,发现中断标示为真时,线程自己中断挂起,

轮询的地方和安全点重合,外加上创建对象需要分配内存的地方。

    • 安全区域 (解决 程序“不执行”时进入GC,例如休眠,阻塞)

一段代码区域中,引用关系不会发生变化。可以把安全区域看做是安全点的扩展。

线程执行到安全区域时,标示自己进入安全区,发生GC时,不用管在安全区域中的线程。

线程若离开安全区域,检查是否已完成了根节点枚举,若完成了线程继续执行,否则线程必须等待,

直到收到可以离开安全区的信号为止。