Java垃圾回收

Java GC()
Java怎么进行自动垃圾回收呢?总得来说就是先找到需要回收的对象,然后回收对象占用内存。

标记

要回收垃圾,先要识别垃圾,Java采用标记的方式识别等待销毁的对象,然后对标记的垃圾再通过回收算法进行回收。

标记算法

  1. 引用计数,对象没有被其他对象或者变量引用时,标记为垃圾。

    缺点:无法解决重复引用问题,导致垃圾不会被回收。如对象A引用对象B,对象B又引用对象B,A和B相互引用,这时候A和B都需要销毁时,引用计数算法无法识别这种需要回收的对象。

  2. 根引用,root引用法,从栈中局部变量、方法区全局变量出发,没有被引用到的对象,识别为垃圾。

回收算法

  1. 标记清除

    标记需要回收的对象,然后回收对象,产生内存碎片,浪费资源。如红色的内存被标记为垃圾,回收后会产生大量的内存碎片,内存使用率不高。
    在这里插入图片描述

  2. 复制
    标记需要回收的对象,不需要回收的对象复制到一块空区域,回收原来的整块区域。堆内的新生代采用此回收算法。
    特点:解决了内存碎片
    缺点:需要额外内存空间,且复制数据性能差。

如标记为红色的垃圾:
在这里插入图片描述

通过复制算法回收后,内存变为:
在这里插入图片描述
3. 标记整理

标记垃圾,将不需要回收的对象整理大一起,回收原来占用的空间。
特点:没有内存碎片,也不浪费内存,但是比较耗时
如内存段A,回收后变为:
在这里插入图片描述

  1. 内存分代,Java采用的回收机制

    堆内存分为年轻代,老年代
    minorGC,回收年轻代,标记复制算法
    FullGC,回收老年代,标记整理算法
    MixedGC,G1模式下发生,回收整个年轻代和部分老年代

垃圾回收器

根据回收的内存区域不同,分为:

  • 新生代回收器
  • 老年代回收器
  • 新生代老年代结合的整堆回收器

新生代回收器

Serial,单线程,简单高效,适用于单核cpu的环境,期间需要Stop the world

ParNew,多线程回收,开启和CPU核心数相同的线程,期间需要Stop the world

ParallelScavenge,并行的多线程垃圾回收器,吞吐量优先。可以根据系统的运行状况调节虚拟机参数,新生代大小,eden区和Suvivor去的比例,以及晋升老年代的对象年龄阈值。

老年代回收器

serial Old,serial收集器的老年代版本

Parallel old,parallel收集器的老年代版本

CMS收集器,以最短停顿时间为目标的回收策略,基于标记-清除算法,并发收集。

收集分为四步:
- 初始标记,标记GCroot能引用到的对象stop the world
- 并发标记:标记GCRoots间接引用的对象,用户线程可并发执行
- 重新标记,修正并发标记期间产生的对象,Stop the world
- 并发清除,对标记的对象进行清除回收

G1
特点:
- 并发并行,充分利用多核CPU,缩短Stop the world时间
- 分代收集,G1收集器可以同时回收老年代和新生代
- 空间整合,采用标记整理算法,不产生内存碎片
- 时间可预测,可以指定在指定时间内,准实时的完成回收,做法是内存分为多个Region,根据Region中垃圾的占用空间大小,维护一个regin的优先级列表,首先回收优先级高的Region,保证有限时间内,更加高效的回收效率。

回收过程:
- 初始标记,标记GCRoots直接引用的对象,stop the world
- 并发标记,标记GCRoots间接可达对象,即间接引用对象,并发执行
- 最终标记,标记并发标记期间产生的变化的对象,对象的变化记录下来,在线程的Remmenber set Log中,stop the world
- 筛选回收,对各个Region分析,排优先级,根据用户期望的回收时间制定回收计划,并发执行回收。

(完^_^)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值