GC垃圾回收策略

垃圾回收策略:针对线程共享内存(堆,方法区)
  • 判断对象是否存活的方法:

    • 引用计数法(Python,c++智能指针):
      1)内容:给每个对象增加一个引用计数器,每当有一个引用指向当前对象时,计数器+1,当引用失效时,计数器就-1,任何时刻计数器为0的对象就是不能再被使用的,即对象已死。
      2). 缺点:无法解决循环引用问题(我中有你,你中有我)

    • 可达性分析法(Java,C#,Lisp):通过一系列称为“GC Roots”的对象作为起始点,从这些节点开始向下搜索,搜索走过的路径称之为“引用链”,当一个对象到“GC Roots”没有任何的引用链相连时(称为不可达),说此对象是不可用的。

      • 哪些对象可以作为GC Roots:
    1. 虚拟机栈与本地方法栈中的临时变量指向的对象
    2. 类中静态变量引用的对象
    3. 类中常量引用的对象
JDK1.2 之后关于引用的扩充:(强软弱虚,引用强度依次递减)
  1. 强引用:程序中普遍存在的,GC Roots指向的引用都属于强引用
    CricleReferenceProblem obj1 = new CricleReferenceProblem();
    只要当前对象被任意一个强引用指向,即便内存不够也不能回收此对象。
  2. 软引用:描述一些有用但不是必须的对象,比如缓存对象;
    强度:当当前系统内存够用时,仅被软引用指向的对象还存活;若当前内存不够用,则下次GC时,会将所有仅被软引用指向的对象进行GC。
    SoftReference来表示软引用
public class SoftReferenceTest{
     private static final int_1MB = 1024*1024;
     private byte[] data = new byte[2*_1MB];
     public static void main(String[] args) {
     	SoftReferenceTest test = new SoftReferenceTest();
     	SoftReference<SoftReferenceTest> softReference = new SoftReference<>(test);
        test = null;
        System.gc();
     }
}
  1. 弱引用
    描述非必须对象,但是强度要弱于软引用。
    仅被弱引用指向的对象,只能存活到下次GC之前,当GC开始时,不管内存是否够用,都会回收仅被弱引用指向的对象。
    jdk1.2:WeakReference类来表示弱引用。
  2. 虚引用
    被称为幽灵引用或幻影引用,它是最弱的一种引用
    一个对象是否有虚引用的存在,完全不会对其生存周期产生影响,也无法通过虚引用得到一个对象实例。
    设置虚引用的唯一目的:该对象被gc之前会由系统发回回收通知。
    jdk1.2 用PhantomReference类表示虚引用
  • 当一个对象到GC Roots不可达,就一定会当场去世?(finalize()对象自我拯救)

    答:不一定,JVM在进行GC之前,需要判断即将回收的对象所在的类是否覆写了Object类中的finalize()方法,
    若没覆写,则此对象直接被回收
    若覆写了:1.若finalize()方法未被JVM调用,会调用finalize()方法,若对象在此次调用过程中与GC Roots有对象可达,则此对象不再被回收。
    2.若finalize()方法已被JVM调用,此对象直接被回收。

  • 简述Java中final,finally,finalize

    • final:终结器
      被final修饰的类不能有子类
      被final修饰的值不能修改
      被final修饰的方法不能被覆写
    • finally:
      用在异常体系中,finally代码块里的代码一定会被执行
      作用:保证重点代码一定会被执行(流的关闭,数据库资源的关闭)
    • finalize:
      Object类中的一个方法,对象的自我拯救;
      作用:JVM在进行GC之前,需要判断即将回收的对象所在的类是否覆写了Object类中的finalize()方法。若没覆写,则此对象直接被回收。若覆写了:
      1.若finalize()方法未被JVM调用,会调用finalize()方法,若对象在此次调用过程中与GC Roots有对象可达,则此对象不再被回收。
      2.若finalize()方法已被JVM调用,此对象直接被回收。
  • 已经死亡的对象如何进行垃圾回收:

    • 方法区的回收(永久代回收):回收废弃常量和无用的类。GC频率非常低,几乎不怎么回收。
      • 废弃常量: 假如一个字符串“abc”进入了常量池,但当前系统没有任何一个String对象引用常量池的“abc”常量,也没有在其他地方引用这个字面量,如果此时发生GC并且有必要的话,这个“abc”常量会被系统清理出常量池。常量池中的其他类(接口),方法,字段的符号引用也与此类似
    • 无用的类:同时满足下面三个条件才是无用类
      该类所有实例都已被回收
      加载该类的ClassLoader(类加载器)已经被回收
      该类对应的Class对象没有在任何其他地方被引用,无法在任何地方通过反射访问该类的方法
  • 堆上的垃圾回收:

    • 堆(所有对象和数组对象)
      • 新生代:对象默认先在新生代产生,大部分对象在此区域存放,该区域特点:对象“朝生夕死”(存活率很低)
      • 老年代:存活率很高
    • 标记清除法:
      • 标记出需要回收的所以对象。
      • 清除阶段统一回收被标记的对象。
      • 缺陷:效率不高,标记清除会产生大量的不连续空间碎片,导致gc频繁发生。
    • 复制算法(新生代垃圾回收算法)超重要:
      核心思想:将可用内存按照容量划分为大小相等的两块,每次只使用其中一块,当这块内存需要进行垃圾回收时,会将此区域还存活着的对象复制到另一块上面,然后再把已经使用过的内存区域一次清理掉。经调查,新生代中98%的对象存活率都很低,所以不需要1:1来划分内存空间,将新生代内存划分为一块较大的Eden(伊甸园)和两块内容较小的Survivor(幸存者)空间,默认比例8:1:1,每次使用Eden和其中一块Survivor(两个Survivor一个称为From区,另一个称为To区域)。
      • step1:对象默认都在Eden区产生,当Eden空间即将满时,触发第一次Minor GC(新生代GC),将Eden区所有存活对象复制到from区,然后一次性清理掉Eden区的所有空间。
      • step2:当Eden空间再次即将满时,触发Minor GC,此时需要将Eden和From区的所有存活对象复制到To区,然后一次清理掉Eden和From区的所有空间。
      • step3:之后的新生代GC,重复阶段2,(From和To区来回作为备用区)。
      • step4:当一个对象一直在From和To区来回交换软干次(默认15次),就将此对象置入老年代空间。
    • 标记整理算法(老年代的垃圾回收算法)
      核心思想:相较于标记清除,先在整理阶段让存活对象向一端移动,然后清理掉存活对象边界之外的所有空间。
      • 为何老年代不采用复制算法:老年代存活率很高,利用复制算法存活对象很多,效率极低。
    • 分代收集策略(Java采用的)
      • 将堆空间分为新生代(-Xmn)与老年代(堆的大小-Xmn)空间,其中新生代次用复制算法,老年代采用标记整理算法。
  • 请问了解Minor GC和Full GC吗,这两种GC有什么区别:
    答:1)Minor GC称为新生代GC,是发生在新生代的垃圾回收,Java对象大多存活率低,所以Minor GC非常频繁的采用复制算法,一般回收速度也很快。
    2)Full GC称为老年代GC或Major GC,是发生在老年代的垃圾回收,出现Major GC通常会伴随至少一次的Minor GC(并非绝对),Major GC 的速度一般比Minor GC慢10倍以上。

  • 垃圾回收算法

    • 对象的分配策略:
      • 对象默认在新生代的Eden区产生
      • 大对象直接进入老年代(-XX:PretenureSizeThreshold)
      • 长期存活对象(默认15)进入老年代。
      • 动态年龄判断:若From或To区的相同年龄对象总和超过Survivor空间的一半,将所有此年龄对象直接晋级老年代。
  • JVM内置的检测工具

    • jps: JVM Process Status Tool—显示指定系统内所有的HotSpot虚拟机进程,返回当前操作系统中所有JVM进程ID。jsp -l(输出包名.类名)
    • jmap: JVM Memory Map—查看当前JVM的内存情况,尤其是堆上的情况。jmap -head PID(查看PID的JVM的堆情况)
    • jstack: 查看当前JVM的线程栈情况,常用于解决线程卡死问题。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值