垃圾回收机制

自动垃圾收集

自动垃圾收集是查看堆内存,识别正在使用哪些对象,以及哪些对象未被删除,以及删除未使用对象的过程。

使用中的对象或引用的对象,意味着程序的某些部分仍然维护指向该对象的指针。
程序的任何部分都不在引用未使用的对象或未引用的对象,因此可以回收未引用对象使用的内存。

像C这样的编程语言中,分配和释放内存是一个手动过程。
在Java中,解除分配内存的过程由垃圾收集器自动处理。

如何确定内存需要被回收

第一步称为标记。这是垃圾收集器识别那些内存正在使用,而哪些不再使用的地方。
在这里插入图片描述
引用计数,会有循环引用的问题。

可达性分析算法

简单来说,将对象及其引用关系看作一个图,选定活动的对象作为GC Roots;
然后跟踪引用链条,如果一个对象和GC Roots之间不可达,也就是不存在引用,那么即可认为是可回收对象

在这里插入图片描述

引用类型和可达性级别

引用类型:

1、强引用(StrongReference):最常见的普通对象引用,只要还有强引用指向一个对象,就不会回收。
2、软引用(SoftReference):JVM认为内存不足时,才会去试图回收软引用指向的对象。(缓存场景)
3、弱引用(WeakReferece):虽然是引用,但随时可能被回收掉。
4、虚引用(PhantomReference):不能通过它访问对象。提供了对象被finalize以后,执行指定逻辑的机制(Cleaner)。

可达性级别

1、强可达(Strongly Reachable):一个对象可以有一个或多个线程可以不通过各种引用访问到的情况。
2、软可达(Softl Reachable):就是当我们只能通过软引用才能访问到对象的状态。
3、弱可达(Weakly Reachable):只能通过弱引用访问时的状态。当弱引用被清楚的时候,就符合销毁条件。
4、幻象可达(Phantom Reachable):不存在其他引用,并且finalize过了,只有幻象引用指向这个对象。
5、不可达(unreachable):意味着对象可以被清除了。

垃圾收集算法

标记—清除(Mark-Sweep)算法:首先标识出所有要回收的对象,然后进行清除。
标记、清除过程效率有限,有内存碎片化问题,不适合特别大的堆;收集算法基本基于标记—清除的思路进行改进。

复制(Copying)算法:划分两块同等大小的区域,收集时将活着的对象复制到另一块区域。
拷贝过程中将对象顺序放置,就可以避免内存碎片化。复制+预留内存,有一定的浪费。

标记—整理(Mark-Compact):类似于标记—清除,但为避免内存碎片化,它会在清理过程中将对象移动,以确保移动后的对象占用连续的内存空间。

分代算法

根据对象的存活周期,将内存划分为几个区域,不同区域采用合适的垃圾收集算法。
新对象会分配到Eden,如果超过-XX:+PretenureSizeThreshold:设置最大对象直接进入老年代的阈值。
在这里插入图片描述
1、新生代内存不够,新生成的对象,直接进入到老年代
2、大对象被创建,直接进入老年代
3、对于年纪大(经历过多次GC)的新生代,进入到老年代
在这里插入图片描述

垃圾收集器

串行收集器 - Serial GC -XX:+UseSerialGC

单个线程来执行所有垃圾收集工作,适合单处理器及其。
Client模式下,JVM的默认选项
串行收集器 - Serial Old -XX:+UseSerialOldGC
可以在老年代使用,它采用了标记—整理(Mark-Compact)算法,区别于新生代的复制算法。
在这里插入图片描述

并行收集器 -Parallel GC -XX:+UseParallelGC

并行收集器 - Parallel Old GC -XX:+UseParallelOldGC
server模式JVM的默认GC选择,整体算法和Serial比较相似,区别是新生代和老年代GC都是并行进行;
可以设置GC时间或吞吐量等值,可以自动进行适应性调整Eden,Survivor大小和MaxTenuringThreshold的值。

也称为吞吐量优先的GC:吞吐量 = 用户代码运行时间 / (用户代码运行时间 + GC时间)

-XX:ParallelGCThreads:设置用于垃圾回收的线程数。通常情况下可以和CPU数量相等。
-XX:MaxGCPauseMills:设置最大垃圾收集停顿时间。它的值是一个大于0的整数。
-XX:GCTimeRatio:设置吞吐量大小,他的值是一个0-100之间的整数。
-XX:+UseAdaptiveSizePolicy:打开自适应GC策略。以达到在堆大小、吞吐量和停顿时间之间的平衡点。

并发收集器 - CMS(Concurrent Mark Sweep) GC -XX:+UseConcMarkSweepGC

专用老年代,基于标记—清除(Mark-Sweep)算法,设计目标是尽量减少停顿时间。
采用的标记—清除算法,存在着内存碎片化问题,长时间运行等情况下发生full GC,导致恶劣的停顿。
CMS会占用更多的CPU资源,并和用户线程争抢。
减少了停顿时间,这一点对于互联网web等对时间敏感的系统非常重要,一直到今天,仍然有很多系统使用CMSGC。
在这里插入图片描述

并行收集器 - ParNew GC -XX:+UseParNewGC

新生代GC实现,它实际是Serial GC的多线程版本。
可以控制线程数量,参数: -XX:ParallelGCThreads
最常见的应用场景是配合老年代的CMS GC工作。参数-XX:+UseConcMarkSweepGC
在这里插入图片描述

并发收集器 - G1 -XX:+UseG1GC

针对大堆内存设计的收集器,兼顾吞吐量和停顿时间,JDK9后,为默认选型,目标是替代CMS;
G1将堆分成固定大小的区域,Region之间是复制算法,但整体上实际可看作是标记—整理(Mark-Compact)算法,可以有效的避免内存碎片。红色新生代(Eden和Surivor),淡蓝色老年代。找不到大内存时执行Full GC。
在这里插入图片描述

垃圾收集器组合

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值