jvm(三) 垃圾回收


在这里插入图片描述

如何确定一个对象是垃圾

想进行垃圾回收,得先知道什么样的对象是垃圾

引用计数法

如果一个对象没有任何指针对他引用,他就是垃圾
缺点:如果存在A/B相互引用,会永远无法回收

可达性分析

铜鼓GC Root 的对象,开始向下寻找,看某个对象是否可达
能作为GC Root的:
	类加载器
	Thread
	虚拟机栈的本地变量表
	static 成员
	常量引用
	本地方法栈的变量

垃圾回收算法

标记清除

标记

扫描堆中所有的对象,找出内存中需要回收的对象,标记出来,非常耗时

清除

清除掉被标记的需要回收的对象,释放空间

缺点

标记和清除太耗时间
产生大量的不连续的内存碎片,导致分配大对象时,放不进去而触发另一次垃圾回收

复制算法

将内存华为两块相等的区域,每次只使用其中的一块,当这块内存块使用完了,将还存活的对象复制到另一半上,然后清除已经使用过的内存空间

缺点

利用率低

标记-整理算法

标记过程跟标记清除算法一样,但是后续步骤是让存活的对象都向一端移动,再清理,这样内存就连续了

分代收集算法

年轻代:复制算法(对象生命周期短,yong区复制效率比较高)
老年代:标记清除或者标记整理(对象存活时间长,复制没必要,不如标记再清理)

垃圾收集器

概括下几种类型
单线程+复制+暂停用户-------Serial
多线程+复制+暂停用户------Parnew
平行+复制------ paraller Scanvenge
单线程+标记整理+暂停用户----serial Old
平行+标记整理----paraller Old

在这里插入图片描述

Serial 收集器

是一种单线程收集器,使用一个收集线程去完成垃圾收集,并且在垃圾收集的时候需要暂停其他线程

优点:简单高效
缺点:收集过程需要暂停所有线程
算法:复制算法
适合范围:新生代
应用:client模式下的默认新生代收集器

在这里插入图片描述

ParNew 收集器

可以理解为Serial收集器的多线程版本

优点:多CPU时,效率比Serial高
缺点:收集过程中还是要暂停所有的应用程序线程,单CPU时还比Serial差
算法:复制算法
适用范围:新生代
应用:运行在Server模式下的虚拟机中首选的新生代收集器

在这里插入图片描述

Paraller(平行的) Scavenge(捡垃圾) 收集器

paraller 是一个新生代收集器,也是使用的复制算法的收集器,又是并行的多线程收集器,看上去和ParNew一样,但是Paraller更关注系统的吞吐量

吞吐量=运行用户代码的时间/(运行用户代码的时间+垃圾收集时间)
比如虚拟机总共运行了100分钟,垃圾收集时间用了1分钟,吞吐量=(100-1)/100=99%。

吞吐量越大,意味着垃圾收集的时间越短,用户代码可以充分利用CPU资源

-XX:MaxGCPauseMillis控制最大的垃圾收集停顿时间,
-XX:GCTimeRatio直接设置吞吐量的大小

Serial Old 收集器

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

在这里插入图片描述

Paraller Old 收集器

paraller Old收集器是 Paraller Scavenge 收集器的老年代版本,使用 标记-整理算法进行垃圾回收
吞吐量优先

CMS 收集器

Concurrent Mark Sweep

是老年代的垃圾收集器
是并发的【用户线程和垃圾会输线程可以同时执行】
标记-清除算法
追求最短回收停顿时间
适合互联网站和B/S系统的服务端

步骤

1、初始标记	标记GC Root能关联到的对象 stw
2、并发标记	GC Roots Tracing
3、重新标记	修改并发标记因用户程序变动的内容 stw
4、并发清除	

优点:并发收集、停顿低
缺点:产生大量的空间碎片、并发阶段降低吞吐量

在这里插入图片描述

G1 收集器

面向服务端的收集器

特点:

并发与并行
分代收集
标记-整理算法
可预测的停顿(可以设置垃圾收集消耗的时间不能超过N毫秒)

原理

G1将整个java堆划分为多个大小相等独立的区域,使得新生代和老年代不再物理隔离

步骤:

1、初始标记 
		标记GC Roots能关联到的对象,修改TAMS值,stw
2、并发标记
		从GC Roots进行可达性分析,找出存活对象,与用户并发执行
3、最终标记
		修正在并发标记阶段因为用户程序的并发执行导致变动的数据,stw
4、筛选回收
	对各个区域的回收价值和成本进行排序,根据用户所期望的GC停顿时间制定回收计划

在这里插入图片描述

垃圾收集器分类

串行收集器

Serial 和Serial Old
只能有一个垃圾回收线程,用户线程暂停

并行收集器[吞吐量优先]

Paraller Scanvege、Paraller Old
多条垃圾收集器并行干工作,但是用户线程仍然需要处于等待状态

并发收集器【停段时间优先】

CMS、G1
用户线程和垃圾收集器同时执行,垃圾收集器在执行的时候不会停顿用户线程

吞吐量和停顿时间

停顿时间:垃圾收集器进行垃圾回收终端应用执行响应的时间
吞吐量:运行用户代码时间/(运行用户代码时间+垃圾收集时间)

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

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

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

再次理解G1

	判断是否需要使用G1收集器
	(1)50%以上的堆被存活对象占用
	(2)对象分配和晋升的速度变化非常大
	(3)垃圾回收时间比较长

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

	(1)串行
			-XX:+UseSerialGC
			-XX:+UseSerialOldGC
	(2)并行(吞吐量优先):
			-XX:+UseParallelGC
			-XX:+UseParallelOldGC
	(3)并发收集器(响应时间优先)
			-XX:+UseConcMarkSweepGC
			-XX:+UseG1GC
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值