Java的垃圾回收器

一、垃圾回收中的主要概念
1.stop-the-world
a.任何一种GC算法中都会发生。
b.当Stop-the-World发生时,除了GC所需的线程以外,所有线程都处于等待状态直到GC任务完成。
c.事实上GC优化很多时候就是指减少Stop-the-World发生的时间,从而使系统具有 高吞吐 、低停顿的特点。
2.Safepoint
a.分析过程中对象引用关系不会发送变化的点
b.产生Safepoint的地方:方法调用;循环跳转;异常跳转等
c:安全点数量得适中
二、JVM的运行模式
1.Server
2.Client
Client模式启动速度较快,Server模式启动较慢;但是启动进入稳定期长期运行之后Server模式的程序运行速度比Client要快很多。这是因为Server模式启动的JVM采用的是重量级的虚拟机,对程序采用了更多的优化;而Client模式启动的JVM采用的是轻量级的虚拟机。所以Server启动慢,但稳定后速度比Client远远要快。
使用Java -version命令就能显示出当前虚拟机处于哪种模式。
三、常见的垃圾回收器

虚拟机所处的区域说明它是属于新生代的收集器还是老年代收集器,如果两个收集器之间有连线说明它们可以搭配使用
为什么老年代中的CMS收集器不能与年轻代中的Parallel Scavenge并存呢?
CMS是HotSport在jdk5推出的第一款真正意义上的并发收集器,第一次实现了让垃圾收集线程与用户线程同时工作,CMS作为老年代收集器无法与jdk4存在的新生代收集器Parallel Scavenge配合工作,因为Parallel Scavenge和G1都没有使用传统的GC收集器代码框架,而是另外独立实现的,其余的集中收集器共用了部分代码,因此它们能够结合在一起相互使用。

四、常见的新生代垃圾回收器
1.Serial回收器(-XX:+UseSerialGC,复制算法)
a.单线程收集,进行垃圾收集时,必须暂停所有工作线程
b.简单高效,Client模式下默认的年轻代收集器
在这里插入图片描述

2.ParNew回收器(-XX:+UseParNewGC,复制算法)
a.多线程收集,其余的行为、特点和Serial收集器一样
b.单核执行效率不如Serial,在多核下执行才有优势
c.Server模式下首选的年轻代收集器。
d.在Server模式下,ParNew收集器是一个非常重要的收集器,因为除了Serial收集器外,目前只有它能与CMS收集器配合工作
在这里插入图片描述

3.Parallel Scavenge回收器(-XX:+UserParallelGC,复制算法)
a.比起关注用户的线程停顿时间,更关注系统的吞吐量(吞吐量:运行用户代码时间/(运行用户代码时间+垃圾回收时间))
b.在多核下执行才有优势,Server模式下默认的年轻代收集器
c.高吞吐量可以高效利用cpu时间,尽可能快的完成运算,适合在后台运算而不需要太多交互的任务。
在这里插入图片描述
五、常见的老年代垃圾收集器
1.Serial Old收集器(-XX:+UseSerialOldGC,标记-整理算法)
a.单线程收集,进行垃圾收集时,必须暂停所有工作线程
b.简单高效,Client模式下默认的老年代收集器
c.除了标记算法不是复制算法,而是标记整理算法之外,其他特点是与新生代里的Serial收集器一模一样的。
在这里插入图片描述
2.Parallele Old收集器(-XX:+UseParallelOldGC,标记整理算法)
a.多线程,吞吐量优先
b.在对吞吐量以及CPU资源敏感的场合都可以优先考虑Parallel Scavenge+Parallel old收集器。
在这里插入图片描述
3.CMS收集器(-XX:+UseConcMarkSweepGC,标记-清除算法)
a.CMS收集器几乎占据着JVM老年代垃圾收集器的半壁江山,它划时代的意义就是垃圾回收线程几乎能与用户线程做到同时工作,尽可能地缩短了”stop-the-world”的停顿时间,如果你的应用程序对停顿比较敏感,并且在应用程序运行的时候可以提供更大的内存和更多的cpu,那么使用CMS收集器会带来好处。
b.它整个垃圾回收过程可以分为以下六步:
(1)初始标记:STW(Stop The Word)。这个过程从垃圾回收的"根对象"开始,只扫描到能够和"根对象"直接关联的对象,并作标记。所以这个过程虽然暂停了整个JVM,但是很快就完成了。
(2)并发标记:这个阶段紧随初始标记阶段,在初始标记的基础上继续向下追溯标记。并发标记阶段,应用程序的线程和并发标记的线程并发执行,所以用户不会感受到停顿。
(3)并发预清理:在这个阶段,虚拟机查找在执行并发标记阶段新进入老年代的对象(可能会有一些对象从新生代晋升到老年代, 或者有一些对象被分配到老年代)。通过重新扫描,减少下一个阶段"重新标记"的工作,因为下一个阶段会Stop The World。
(4)重新标记:这个阶段会暂停虚拟机,收集器线程扫描在CMS堆中剩余的对象。扫描从"根对象"开始向下追溯,并处理对象关联
(5)并发清理:清理垃圾对象,这个阶段收集器线程和应用程序线程并发执行。
(6)并发重置:这个阶段,重置CMS收集器的数据结构,等待下一次垃圾回收。

这六个阶段只有初始标记和重新标记需要短暂的stop-the-world。

在这里插入图片描述
并发标记的过程实际上就是和用户线程同时工作,也就是一边丢垃圾一边打扫。这样就会带来一个问题,如果垃圾的产生是在标记后发生,那么这次垃圾就只有等到下次再回收,当然等到垃圾标记了过后,垃圾自然不会和用户线程产生冲突。而清理过程就能和用户同时处理了。
对于此垃圾回收器有一个显著且不可避免的一个问题,就是它所采用的是标记-清除算法,它不会压缩成坨的对象,这样就会带来内存空间碎片化的问题。
4.G1收集器(-XX:+UseG1GC,复制+标记-整理算法)
a.既用于年轻代也用于老年代的收集器.在Garbage First之前的收集器收集范围都是整个年轻代或者老年代的,Garbage First不再是这样。
b.使用多个CPU来缩短stop-the-world的停顿时间,与用户线程并发执行
c.分代收集
d.空间整合。基于标记-整理算法,无内存碎片产生。
e.可预测的停顿。能建立可预测的停顿时间模型,能让使用者明确指定在一个长度为M毫秒的时间片段内,消耗在垃圾收集上的时间不得超过N毫秒。
f.将整个Java堆划分为多个大小相等的独立区域(Region),虽然还保留有新生代和老年代的概念,但新生代和老年代不再是物理隔离的了,它们都是一部分Region(不需要连续)的集合。
这就意味着这分配空间时,不需要一个连续的内存空间,即不需要JVM在启动时决定哪些region是属于老年代,哪些属于年轻代。
因为随着时间推移,年轻代region被回收以后,就会变成可用状态,这时也可以把它分配成老年代。
在这里插入图片描述
g.G1年轻代收集器是并行Stop-the-world收集器,和其他的HotSpot GC一样,当一个年轻代GC发生时,整个年轻代被回收。G1的老年代收集器有所不同,它在老年代不需要整个老年代回收,只有一部分Region被调用。

G1 GC的年轻代由Eden Region和Survivor Region组成。当一个JVM分配Eden Region失败后就触发一个年轻代回收,这意味着Eden区间满了。然后GC开始释放空间,第一个年轻代收集器会移动所有的存储对象从Eden Region到Survivor Region,这就是“Copy to Survivor”过程。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值