JVM学习(4)-- GC(Garbage Collection 垃圾收集)

目录

GC(Garbage Collection 垃圾收集)

如何确定一个对象是垃圾

引用计数法

可达性分析

垃圾回收算法

标记-清除(Mark-Sweep)

复制算法(Copying)

标记-整理(Mark-Compact)

分代回收算法

垃圾收集器

serial收集器

ParNew收集器

Parallel Scavenge收集器

Serial Old收集器

Parallel Old收集器

CMS收集器

G1收集器

垃圾收集器分类

吞吐量和停顿时间

如何选择合适的垃圾收集器

如何开启需要的垃圾收集器


GC(Garbage Collection 垃圾收集)

如何确定一个对象是垃圾

引用计数法

对于某个对象而言,只要应用程序中持有该对象的引用,就说明该对象不是垃圾,如果一个对象没有任 何指针对其
引用,它就是垃圾。
弊端:如果AB相互持有引用,导致永远不能被回收。

可达性分析

通过GC Root的对象,开始向下寻找,看某个对象是否可达;

能作为GCroot的:类加载器、Thread、虚拟机栈的本地变量表、static成员、常量引用、本地方法栈的变量。

虚拟机栈(栈帧中的本地变量表)中引用的对象。
方法区中类静态属性引用的对象。
方法区中常量引用的对象。
本地方法栈中 JNI (即一般说的 Native 方法)引用的对象。

垃圾回收算法

标记-清除(Mark-Sweep)

找出内存中需要回收的对象,并且把它们标记出来, 此时堆中所有的对象都会被扫描一遍,从而才能确定需要回收的对象,比较耗时。
缺点: 标记清除之后会产生大量不连续的内存碎片,空间碎片太多可能会导致以后在程 序运行过程中需要分配较大对象时,无法找到足够的连续内存而不得不提前触发另一次垃圾收集动作。
(1) 标记和清除两个过程都比较耗时,效率不高
(2) 会产生大量不连续的内存碎片,空间碎片太多可能会导致以后在程序运行过程中需要分配较大对象时,无 法找到足够的连续内存而不得不提前触发另一次垃圾收集动作。

复制算法(Copying)

将内存划分为两块相等的区域,每次只使用其中一块, 当其中一块内存使用完了,就将还存活的对象复制到另外一块上面,然后把已经使用过的内存空间一次 清除掉。
缺点:空间利用率低
复制收集算法在对象存活率较高时就要进行较多的复制操作,效率将会变低。更关键的是,如果
不想浪费 50% 的空间,就需要有额外的空间进行分配担保,以应对被使用的内存中所有对象都有
100% 存活的极端情况,所以老年代一般不能直接选用这种算法。

标记-整理(Mark-Compact)

让所有存活 的对象都向一端移动,然后直接清理掉端边界以外的内存。
 

分代回收算法

Young 区:复制算法 ( 对象在被分配之后,可能生命周期比较短, Young 区复制效率比较高 )
Old 区:标记清除或标记整理 (Old 区对象存活时间比较长,复制来复制去没必要,不如做个标记再清理 )

垃圾收集器

serial收集器

Serial 收集器是最基本、发展历史最悠久的收集器,曾经(在 JDK1.3.1 之前)是虚拟机新生代收集的唯 一选择.
它是一种单线程收集器,不仅仅意味着它只会使用一个 CPU 或者一条收集线程去完成垃圾收集工作,更 重要的是其在进行垃圾收集的时候需要暂停其他线程。
 
优点:简单高效,拥有很高的单线程收集效率
缺点:收集过程需要暂停所有线程
算法:复制算法
适用范围:新生代
应用: Client 模式下的默认新生代收集器

ParNew收集器

可以把这个收集器理解为 Serial 收集器的多线程版本。
 
优点:在多 CPU 时,比 Serial 效率高。
缺点:收集过程暂停所有应用程序线程,单 CPU 时比 Serial 效率差。
算法:复制算法
适用范围:新生代
应用:运行在 Server 模式下的虚拟机中首选的新生代收集器

Parallel Scavenge收集器

Parallel Scavenge 收集器是一个新生代收集器,它也是使用复制算法的收集器,又是并行的多线程收集 器,看上去和 ParNew 一样,但是 Parallel Scanvenge 更关注 系统的吞吐量
 
PS: 吞吐量 = 运行用户代码的时间 /( 运行用户代码的时间 + 垃圾收集时间 )
比如虚拟机总共运行了 100 分钟,垃圾收集时间用了 1 分钟,吞吐量 =(100-1)/100=99%
若吞吐量越大,意味着垃圾收集的时间越短,则用户代码可以充分利用 CPU 资源,尽快完成程序 的运算任务。
-XX:MaxGCPauseMillis 控制最大的垃圾收集停顿时间,
-XX:GCTimeRatio 直接设置吞吐量的大小。
 

Serial Old收集器

Serial Old 收集器是 Serial 收集器的老年代版本,也是一个单线程收集器,不同的是采用 " 标记 - 整理算 " ,运行过程和 Serial 收集器一样。

Parallel Old收集器

Parallel Old 收集器是 Parallel Scavenge 收集器的老年代版本,使用多线程和 " 标记 - 整理算法 " 进行垃圾
回收。

CMS收集器

CMS(Concurrent Mark Sweep)收集器是一种以获取最短回收停顿时间为目标的收集器,采用的是标记清除算法,整个过程分四步。

(1) 初始标记 ->速度很快  标记 GC Roots 能关联到的对象  stop the world
(2)并发标记                    进行 GC Roots Tracing
(3)重新标记                    修改并发标记因用户程序变动的内容  stop the world
(4) 并发清除
由于整个过程中,并发标记和并发清除,收集器线程可以与用户线程一起工作,所以总体上来 说, CMS 收集器的内存回收过程是与用户线程一起并发地执行的
 
优点:并发收集、低停顿
缺点:产生大量空间碎片、并发阶段会降低吞吐量

G1收集器

G1 收集器在 JDK 7 正式作为商用的收集器。
JDK 7 开始使用, JDK 8 非常成熟, JDK 9 默认的垃圾收集器,适用于新老生代。
与前几个收集器相比, G1 有以下特点:
 
并行与并发
分代收集(仍然保留了分代的概念)
空间整合(整体上属于 标记 - 整理 算法,不会导致空间碎片)
可预测的停顿(比 CMS 更先进的地方在于能让使用者明确指定一个长度为 M 毫秒的时间片段内,消耗在垃圾收集 上的时间不得超过 N 毫秒)
G1 收集器会先收集存活对象少的区域,也就是垃圾对象多的区域,这样可以有大量的空间可以释放出来,这就 Garbage First 的由来
 
使用 G1 收集器时, Java 堆的内存布局与就与其他收集器有很大差别,它将整个 Java 堆划分为多个 大小相等的独立区域( Region ),虽然还保留有新生代和老年代的概念,但新生代和老年代不再 是物理隔离的了,它们都是一部分 Region (不需要连续)的集合。
 
工作过程可以分为如下几步:
初始标记:标记一下 GC Roots 能够关联的对象 ,需要暂停用户线程 
并发标记: GC Roots 进行可达性分析,找出存活的对象,与用户线程并发 执行
最终标记:修正在并发标记阶段因为用户程序的并发执行导致变动的数据,需暂停用户线程
筛选回收: 对各个 Region 的回收价值和成本进行排序,根据 用户所期望的 GC 停顿时间制定回收计划
是否使用 G1 收集器?
1 50% 以上的堆被存活对象占用
2 )对象分配和晋升的速度变化非常大
3 )垃圾回收时间比较长
 

垃圾收集器分类

  • 串行收集器:serial和serial old  只能有一个垃圾回收线程执行,用户线程暂停。适用于内存比较小的嵌入式设备
  • 并行收集器[吞吐量优先]:parallel Scanvenge、Parallel Old  多条垃圾收集线程并行工作,但此时用户线程仍然处于等待状态。适用于科学计算、后台处理等若交互场
  • 并发收集器[停顿时间优先]:CMS 、G1  用户线程和垃圾收集线程同时执行(但并不一定是并行的,可能是交替执行的),垃圾收集线程在执行的时候不会停顿用户线程的运行。适用于相对时间有要求的场景,比如Web

吞吐量和停顿时间

停顿时间->垃圾收集器进行垃圾回收终端应用执行响应的时间

吞吐量->运行用户代码时间/(运行用户代码时间+垃圾收集时间)

停顿时间越短就越适合需要和用户交互的程序,良好的响应速度能提升用户体验;
高吞吐量则可以高效地利用 CPU 时间,尽快完成程序的运算任务,主要适合在后台运算而不需要太多交互的任 务。

如何选择合适的垃圾收集器

官网解说

  • 优先调整堆的大小让服务器自己来选择
  • 如果内存小于 100M ,使用串行收集器
  • 如果是单核,并且没有停顿时间要求,使用串行或 JVM 自己选
  • 如果允许停顿时间超过 1 秒,选择并行或 JVM 自己选
  • 如果响应时间最重要,并且不能超过 1 秒,使用并发收集器 对于 G1 收集

如何开启需要的垃圾收集器

1)串行:

-XX +UseSerialGC
-XX +UseSerialOldGC
 
2 )并行 ( 吞吐量优先 )
 
-XX +UseParallelGC
-XX +UseParallelOldGC
 
3 )并发收集器 ( 响应时间优先 )
 
-XX +UseConcMarkSweepGC
-XX +UseG1GC

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值