首页 > 编程语言 >JVM系统优化实践(7):垃圾回收器与垃圾回收算法

JVM系统优化实践(7):垃圾回收器与垃圾回收算法

时间:2023-03-03 22:32:16浏览次数:43  
标签:系统优化 标记 回收 GC 垃圾 线程 CMS

您好,我是湘王,这是我的51CTO博客,欢迎您来,欢迎您再来~




上回说到了年轻代、老年代与数据计算的一个案例。接下来就先讲一讲年轻代和老年代的两个垃圾回收器:ParNew和CMS。

和Serial垃圾回收器一样,ParNew也是对年轻代进行垃圾回收,但Serial垃圾回收器是单线程的,而ParNew是多线程的。

如果要指定使用ParNew垃圾回收器,只需在JVM中开启-XX:+UseParNewGC参数就行了。

JVM系统优化实践(7):垃圾回收器与垃圾回收算法_垃圾回收器


ParNew的默认线程数量和CPU核数一致,如果要调节ParNew线程数量,使用-XX:ParallelGCThreads参数即可,一般不用更改。启动系统时可以分别指定客户端模式与服务器模式,只要在参数后分别跟上-client和-server就行了。客户端模式与服务器模式的区别是:

1、如果部署在类Unix机器上,就用服务器模式;如果部署在Windows上,就是客户端模式;

2、服务器模式通常是多核的大型系统后端;客户端模式通常是给applet这类的客户端程序使用,机器也多为单核。

而老年代的垃圾回收器CMS使用的是标记清理算法:标记出哪些是垃圾对象,然后就把它们清理掉。但这可能会造成内存碎片过多,导致空间严重浪费。因此,CMS采取GC线程 + 工作线程同时执行的方式。

JVM系统优化实践(7):垃圾回收器与垃圾回收算法_老年代_02


CMS的一次典型垃圾回收过程如下:

1、初始标记阶段。初始标记意味着系统要进入Stop the World状态,仅仅标记出所有被GC Roots直接引用的对象(方法的局部变量和静态变量),并不会执行清理。

JVM系统优化实践(7):垃圾回收器与垃圾回收算法_CMS_03


2、并发标记阶段。系统程序恢复运行,GC线程则会尽可能对全部老年代里已有对象进行GC Roots追踪(即弄清全部老年代里的对象是否被引用了)。

JVM系统优化实践(7):垃圾回收器与垃圾回收算法_垃圾回收器_04


3、重新标记阶段。系统程序再次被禁止运行,对在上一阶段程序运行时状态发生变更的对象进行标记。

JVM系统优化实践(7):垃圾回收器与垃圾回收算法_垃圾回收器_05


4、最后是并发清理阶段。系统程序再次恢复运行,清理掉之前标记为垃圾的对象即可。

JVM系统优化实践(7):垃圾回收器与垃圾回收算法_CMS_06


因此这就可以解释为什么老年代会比年轻代速度慢很多了。主要就是CMS会导致资源紧张。系统线程和GC线程同时工作,会导致有限的CPU资源被占用,尤其是进行GC Roots时。

CMS默认启动的GC线程数量 = (CPU核数 + 3) / 4。

在第四阶段(即并发清理阶段),会产生浮动垃圾,即GC本身产生的新垃圾。

JVM系统优化实践(7):垃圾回收器与垃圾回收算法_老年代_07


浮动垃圾要等到下一次Minor GC时才会被回收。所以JVM会预留一些空间,保证在CMS期间让存活对象能进入老年代。前面也说过CMS的触发时机就是当老年代内存占用达到一定比例时启动。-XX:CMSInitiatingOccupancyFraction参数就是用来设置这个阈值,超过设定值则开启CMS(JDK1.8已不建议使用)。JDK8的默认比例值是92%,具体原因可以参考这个官方链接:https://docs.oracle.com/javase/8/docs/technotes/guides/vm/gctuning/cms.html

另外,CMS执行时会遇到一个Concurrent Mode Failure问题:也就是当要进入到老年代的存活对象大于可用内存空间时,意味着CMS执行失败。此时会自动用Serial Old代替CMS——强行Stop the World,垃圾回收完成后再恢复系统线程。

执行GC时产生的内存碎片由这两个JVM参数决定:

1、-XX:UseCMSCompactAtFullCollection参数会默认打开,避免CMS产生的内存碎片问题,意思是Full GC之后再次进行Stop the World,清理碎片(JDK1.8已不建议使用);

2、-XX:CMSFullGCsBeforeCompaction参数表示执行多少次Full GC之后再进行碎片清理(默认0,表示每次都清理,JDK1.8已不建议使用)。




感谢您的大驾光临!咨询技术、产品、运营和管理相关问题,请关注后留言。欢迎骚扰,不胜荣幸~

标签:系统优化,标记,回收,GC,垃圾,线程,CMS
From: https://blog.51cto.com/u_15817148/6099141

相关文章

  • 垃圾回收相关概念整理
    1引用跟踪算法CLR使用一种引用跟踪算法来确实对象是否回收。2根所有引用类型的变量都叫根。3活动根活动根分为三种:当前正在执行的方法(或在其调用栈的任何一......
  • 1757. 可回收且低脂的产品
    题目链接:https://leetcode.cn/problems/recyclable-and-low-fat-products/题目描述: 由题目可知,我们需要查找低脂可回收的产品编号,用一行就可以搞定:SELECTproduct_i......
  • php5和php7垃圾回收的区别
    前言:之前对PHP的GC只是了解了个大概,这次详细了解下PHP的垃圾回收机制(GC)。介于网上大部分都是PHP5.X的GC,虽然php5到php7GC部分做出的改动较小,但我觉得还是一起写下来比......
  • JVM系统优化实践(6):年轻代、老年代与数据计算
    您好,我是湘王,这是我的51CTO博客,欢迎您来,欢迎您再来~上回说道如果当前Survivor区中年龄相同的一批对象总大小≥Survivor总数×50%,那么这批对象及比它们年龄更大的对象,就都......
  • mac上好用10款系统优化软件
    如果你是一名Mac用户,那么你一定希望自己的电脑运行得更加流畅和高效。为了达到这个目的,系统优化软件是必不可少的工具。下面介绍了10款Mac上好用的系统优化软件。1......
  • “堆内存持续占用高 且 ygc回收效果不佳” 排查处理实践
    作者:京东零售王江波说明:部分素材来源于网络,数据分析全为真实数据。一、问题背景自建的两套工具,运行一段时间后均出现内存占用高触发报警,频繁younggc且效果不佳。曾经尝......
  • JVM系统优化实践(5):什么时候GC以及有哪些GC
    您好,我是湘王,这是我的51CTO博客,欢迎您来,欢迎您再来~既然程序运行会产生大量的废弃物,也就是「垃圾」,那总不能一直堆着不管吧。现在就来粗浅地谈谈Java里面什么时候会触发GC以......
  • hdfs清空回收站
    hdfsdfs-du-h查看各个HDFS空间占用情况 hdfs dfs -rmr  /user/fughting/.Trash/Current 就可以清空fighting这个用户的回收站了(但是这种方式并不会删除文......
  • chatGPT在电力系统优化领域的初步测评
    最近终于有时间初步尝试了一下chatGPT,感觉还是很令人吃惊。综合以下几个方面进行评估:知识范围:十分广,基本上电力系统的很多知识都有所了解。表达能力:较强,比较清晰完整。数......
  • JVM系统优化实践(5):什么时候GC以及有哪些GC
    您好,我是湘王,这是我的博客园,欢迎您来,欢迎您再来~   既然程序运行会产生大量的废弃物,也就是「垃圾」,那总不能一直堆着不管吧。现在就来粗浅地谈谈Java里面什么时候会......