java-GC垃圾回收器

GC的主要区域

GC主要回收的是堆中数据

GC判断是否为垃圾对象的俩种方法

  • 引用计数法
  • 可达性算法

引用计数法

是在创建对象后,每添加一个对象的引用,该对象的引用计数器就会加1,如该对象为java方法中的本地对象则在方法调用后会销毁该对象,计数器并减1;直到为0时则会触发垃圾回收

问题?
该垃圾回收机制在遇到循环引用的问题时,则会出现永久不会回收的情况

可达性算法

从GC root起,到堆中每一个相关对象判断是否有引用链可达,若可达则标记为正确,若不可达则判定为垃圾对象,则执行垃圾回收

可以作为GC root的对象

  • 虚拟机栈中引入的对象
  • 元数据区类中常量引用的对象
  • 元数据区类中静态变量引用的对象
  • 本地方法栈中JNI(Native)方法引用的对象
  • 活跃线程的引用对象

垃圾回收算法

  • 标记/清除算法
  • 复制算法
  • 标记整理算法
  • 分代收集算法

标记/清除算法

标记清除算法,借用可达性算法,将不可达对象进行标记,并清除,总共分为俩个阶段:标记阶段与回收阶段

缺点:容易出现碎片化空间
在这里插入图片描述

复制算法

开辟俩片空间,大小相等,将对象默认创建到其中一个区中,当触发垃圾回收时,将存活对象拷贝到另一空间,将当前对象空间进行清理

缺点:空间利用率减少一半
在这里插入图片描述

标记整理算法

其为对标记清除算法的优化,在标记之后对数据进行整理,减少碎片化

在这里插入图片描述

分代收集算法

将堆内存分为不同代,使用不用的回收算法进行回收对象

1.7之前划分年轻代、老年代、永久代,1.7之后废除永久代,引入元数据空间
在这里插入图片描述
年轻代:使用复制算法
老年代:数据存活量大,使用标记-清除算法/标记-整理算法

年轻代对象如何进入老年代?

  • survivor区存不下存活对象
  • 对次年轻代收集后仍存活的对象
  • 新建了一个较大的对象
  • 涉及到相关的jvm调优参数有
    -XX:SurvivorRaion: Eden区与Survivor区的比值,默认为8:1
    -XX:NewRation: 老年代与年轻代的比值,默认为2:1
    -XX:MaxTenuringThreshold:对象从年轻代到老年代经过GC次数最大的阀值

引发FULL GC的条件

  • 老年代空间不足
  • 程序调用System.gc()

垃圾回收关系密切的几个关键字

  • Stop-The-World:解释如下
    • 执行GC时,应用程序终止运行
    • 任何一种GC算法中都会发生
    • 多数GC优化都是通过减少Stop-The-World的时间来提高程序性能
  • SafePoint:解释如下
    • 分析过程中对象引用关系不会发生变化的点
    • 产生SafePoint的地方:方法调用、循环跳转、异常跳转等
    • 安全点数量适中

常用的垃圾回收器

在这里插入图片描述

  • 年轻代常见的垃圾回收器有
    • Serial收集器(-XX:+UseSerialGC,复制算法)
      • 单线程收集,在垃圾收集时,会暂停所有工作线程
      • 简单高效,Client模式下默认的年轻代收集器
    • ParNew收集器(-XX:+UseParNewGC,复制算法)
      • 多线程收集,在垃圾回收时,暂停所有工作线程
      • 单核执行不如Serial,多核有优势
    • Parallel Scavenge收集器(-XX:+UseParallelGC,复制算法)
      • 比起关注用户线程停顿时间,更关注系统的吞吐量
      • 多核下才有优势,Server模式下年轻代默认的垃圾回收器
  • 老年代常见的垃圾回收器有
    • Serial OId收集器(-XX:+UseSerialOldGC,标记-整理算法)
      • 单线程收集,在垃圾收集时,会暂停所有工作线程
      • 简单高效,Client模式下默认的老年代收集器
    • CMS收集器(-XX:+UseConcMarkSweepGC,标记-清除算法)
      • 初始标记:stop-the-world
      • 并发标记:并发追溯标记,程序不会停顿
      • 并发预清理:查找执行并发标记阶段从年轻代晋升到老年代的对象
      • 重新标记:暂停虚拟机,扫描CMS堆中的剩余对象
      • 并发清理:清理垃圾对象,程序不会卡顿
      • 并发重置:重置CMS收集器的数据结构
    • Parallel Old收集器(-XX:+UseParallelOldGC,标记-整理算法)
      • 多线程,更关注系统的吞吐量
  • G1垃圾收集器(-XX:+UseG1GC,复制+标记-整理算法)
    • 并行和并发,垃圾收集线程与工作线程并发执行
    • 分代收集
    • 空间整合
    • 可预测的停顿

垃圾回收的几个问题点

  • finalize()方法
  • 强引用、软引用、弱引用、虚引用的区别
    强引用就是一般创建对象的方式,new方法创建,一般即使内存不够用,也不会主动销毁
	//ArrayList中如何清理对象,相当于将所有对象重为空,等待GC回收
	/**
     * Removes all of the elements from this list.  The list will
     * be empty after this call returns.
     */
    public void clear() {
        modCount++;

        // clear to let GC do its work
        for (int i = 0; i < size; i++)
            elementData[i] = null;

        size = 0;
    }

软引用:软引用是用来描述一些有用但并不是必需的对象,在Java中用java.lang.ref.SoftReference类来表示,当内存不够时,会被GC清理

String str=new String("abc");                                     // 强引用
SoftReference<String> softRef=new SoftReference<String>(str);     // 软引用x
softRef.get() //得到str对象,如果str被回收,则返回null
//当内存不足时
If(JVM.内存不足()) {
  str = null;  // 转换为软引用
  System.gc(); // 垃圾回收器进行回收
}

弱引用:如果一个对象只有弱引用,那么就类似可有可无的生活用品,当JVM进行垃圾回收时,无论内存是否充足,都会回收被弱引用关联的对象。在java中,用java.lang.ref.WeakReference类来表示。
弱引用与软引用的区别是无论内存是否充足,GC都会处理弱引用对象

WeakReference<String> sr = new WeakReference<String>(new String("hello"));
System.out.println(sr.get());
System.gc();                //手工模拟JVM的gc进行垃圾回收
System.out.println(sr.get());

虚引用:“虚引用”顾名思义,就是形同虚设,与其他几种引用都不同,虚引用并不会决定对象的生命周期。在java中用java.lang.ref.PhantomReference类表示。若一个对象只有虚引用,那则可能在任何时刻被JVMGC回收,虚引用与软引用或者弱引用的区别是,其需要依赖于引用队列,当一个对象被GC回收时,判断到其仅有虚引用,则会将这个虚引用加入引用队列,故虚引用一般用于跟踪对象垃圾回收过程的。

  		Object obj = new Object();
        ReferenceQueue<Object> rq = new ReferenceQueue<Object>();
        PhantomReference<Object> pf = new PhantomReference<Object>(obj,rq);
        obj=null;
        System.out.println(pf.get());//永远返回null
        System.out.println(pf.isEnqueued());//返回是否从内存中已经删除
        System.gc();
        TimeUnit.SECONDS.sleep(6);
        System.out.println(pf.isEnqueued());
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值