Java GC 垃圾回收器

一、垃圾定位

没有引用指向的对象被称为垃圾。如何定位垃圾?一般有两种算法,引用计数法 Reference Count,和根可达算法 Root Searching。

1、引用计数法

在对象上标记被指向的个数,count =0的时候可以被回收,无法解决循环引用的问题。

2、根可达算法

从根对象开始搜索,不能跟踪到的对象就是垃圾。

根对象包括线程栈变量,静态变量,常量池,JNI 指针。

二、常见的垃圾回收算法 GC Algorithms

垃圾回收算法 GC Algorithms,就是找到垃圾后怎样进行清除的算法,常用的三种:

1、 标记清除算法 Mark Sweep

就是找到有用的,将没用的标记出来,然后清理掉;算法比较简单,在存活对象比较多的情况下效率较高。

缺点:扫描两遍,效率偏低;容易产生碎片;不适用于Eden区。

2、拷贝算法 Copying

将内存一分为二,将有用的拷贝到一个区域,将没用的全部清除掉;只扫描一次,效率提高,没有碎片,适用于存活对象较少的情况。

缺点:空间浪费,复制移动对象,需要同时调整对象引用;适用于Eden区。

3、标记压缩算法 Mark Compact

把有用的压缩整理到一起,其它没用的全部清除掉;不会产生碎片,方便对象分配,不会产生内存减半。

缺点:扫描两次,需要移动对象,效率偏低。

三、垃圾回收GC触发条件

Minor GC / Young GC,new / young 年轻代空间耗尽时触发。

Major GC / Full GC,old / tenured 老年代空间耗尽时触发,新生代,老年代同时进行回收。

四、常见的垃圾回收器

1、Serial

最开始的时候使用的GC,单一GC线程,使用的是 copying 拷贝算法,用在新生代,单CPU效率高。需要找到一个安全点 safe point,停止线程,进行GC。

2、Serial Old

单线程,使用 mark sweep 标记清除算法,用于老年代。

3、Parallel Scavenge

多线程,copying 算法,用在新生代。

4、Parallel Old

多线程,mark compact 算法,用在老年代。

5、ParNew

多线程,copying 算法,用于新生代,与 Parallel Scavenge相比,做了一些增强,可以和 CMS 同时使用。

6、CMS

Concurrent Mark Sweep,工作线程和GC线程可以同时运行。用于老年代,GC有4个阶段:

1)initial mark,初始标记阶段,只找根对象,进行标记,此阶段有STW,工作线程停止,持续时间短。

2)concurrent mark,并发标记阶段,工作线程运行的同时,标记垃圾。

3)remark,重新标记,停止工作线程,持续时间短,标记在并发标记过程中发生变化的对象,比如之前没有引用的对象增加了一个引用后不再是垃圾。

4)concurrent sweep,并发清理阶段,和工作线程同时运行。

CMS 出现问题的时候,使用 Serial Old 进行标记压缩。

缺点:使用 mark sweep 算法,会产生碎片;并发清理阶段会会产生新的垃圾,也就是浮动垃圾。

7、G1

Java HotSpot VM上,运行在服务器端。通过并行和并发的手段,达到暂停时间特别短(几百毫秒),并且可以维持一个较高的吞吐量;目标是用于多核,大内存的机器上;JDK9 默认GC。

将内存分成一个个region,每个region在逻辑上属于某个分代。这里有四种分代:

1)old区,放老对象

2)survivor区,放存活对象

3)Eden,放新生对象

4)humongous,放大对象,对象特别大的时候可能跨region。

特点:

1)并发搜集

2)压缩空间空间不会延长GC暂停时间

3)GC暂停时间更易预测

4)不需要实现高吞吐量的场景使用

Eden 空间不足时,产生 YGC,多线程并发执行;

Old 空间不足,对象分配不下,或者调用 System.gc()时,产生 FGC;JDK10之前是串行;之后是并行。

G1如果发生FGC,应该怎么办?

1)扩充内存

2)提高CPU 性能

3)降低 MixedGC 触发的阈值,默认是45%,让 MixedGC 提早发生。

MixedGC 的过程?类似一个 CMS 的过程:

1)初始标记 STW

2)并发标记

3)最终标记 STW

4)筛选回收 STW

8、ZGC

JDK11,只支持 Linux / x86_64。

9、Shanondoah

CMS 和 G1都是使用三色标记,ZGC 和 Shenandoah 使用颜色指针 Color Pointer。

吞吐量优先的程序选择 PS + PO;追求响应时间的选择 CMS,G1(JDK8),ZGC。

五、查看默认垃圾回收器

查看命令:

java -XX:+PrintCommandLineFlags -version

这个参数意思是查看使用的 JVM 默认参数。

 JDK 8默认使用 PS + PO,新生代采用的是Parallel Scavenge,老年代Parallel Old。

-XX:+PrintGC,打印GC回收信息

-XX:+PrintGCDetails,打印GC回收详细信息

-XX:+PrintGCTimeStamps,打印GC回收时间信息

-Xmn10M -Xms40M -Xmx40M,分别指定新生代大小,最小堆大小,最大堆大小

使用CMS回收器通过下面这个参数指定:-XX:+UseConcMarkSweepGC。

实际用到的 GC 为 ParNew,CMS,Serial Old。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值