首页 > 其他分享 >垃圾回收过程可设置的参数

垃圾回收过程可设置的参数

时间:2023-11-25 10:03:50浏览次数:36  
标签:对象 新生代 回收 XX GC 垃圾 参数

1内存分代

  • 垃圾回收主要是在堆没有足够的内存空间来存放新创建的对象时被触发。由于堆中的对象生命周期不同,故在进行垃圾回收时,不是所有对象都需要被回收,只是回收不再可达的对象。同时在进行垃圾回收时需要暂停应用程序,故会造成应用在暂停期间不可用,垃圾回收持续的时间越长,则应用不可用越久。而垃圾回收由于要基于对象可达性分析确定需要回收哪些对象,故持续时间与需要扫描和分析的内存区域的大小相关。
  • 基于以上分析,为了尽量减少应用停顿时间,JVM根据对象生命周期的长短,基于分代的思路,将堆进一步细分为新生代和老年代两个区域,从而缩小垃圾回收需要扫描和分析的内存范围。新生代和老年代的大小比例可以通过JVM参数:-XX:NewRatio来控制,默认新生代和老年代大小比例为1:2,新生代占堆的1/3,即-XX:NewRatio=2。或者通过 -XX:NewSize来指定新生代的初始大小, -XX:MaxNewSize来指定新生代的最大大小,如果NewRatio和NewSize同时存在,在NewSize和MaxNewSize覆盖NewRatio。
  • 每次新创建的对象都放在新生代中,如果新生代没有足够的内存空间来存放新对象时,先只对新生代进行垃圾回收来获取内存空间,这个过程称为Minor GC。如果对新生代进行垃圾回收之后还是没有充足的内存空间,则同时对新生代和老年代,即整个堆进行垃圾回收,这个过程称为Full GC。Minor GC持续时间较短,对应用影响较小,Full GC持续时间较长,对应用影响较大。
  • 老年代主要存放年龄较大或者需要占用较大内存空间的对象:
  • 通过JVM参数:-XX:MaxTenuringThreshold=xx来控制晋升到老年代对象的年龄,不同GC收集器实现不同,Parallel Scavenge中默认值为15,CMS中默认值为6,G1中默认值为15,如果设置为0则新对象直接放到老年代。每进行一次Minor GC存活对象的年龄加一;
  • 通过JVM参数:-XX:PretenureSizeThreshold=xx(单位为字节)来控制超过这个大小的对象直接在老年代分配内存空间,默认为0,表示都首先在新生代分配。
  • 对堆基于分代的思路细分之后,由于新生代和老年代中存放的对象特点不一样,故对新生代和老年代的垃圾回收算法也存在差别,对应新生代是基于复制算法来实现回收的,老年代是基于标记清除或标记压缩算法来回收的。

2垃圾回收算法

复制算法

  • 每个新创建的对象都首先在新生代分配内存来存放,新生代的对象的特点是生命周期很短,即大部分都是存放一段时间后变为不可达,即可以被回收,故在对新生代进行垃圾回收时,可以回收大部分的对象。
  • 基于新生代存放的对象生命周期短,每次存活对象较少的特点,新生代主要是基于复制算法来实现垃圾回收。算法实现为:将新生代进一步细分为Eden,From Survivor,To Survivor三个区域,新创建的对象都存放在Eden。其中From和To的大小是相同的,可以通过JVM参数:-XX:SurvivorRatio来控制Eden和Survivor大小比例,默认为Eden和Survivor为8 : 2,-XX:SurvivorRatio=8,即Eden大小为新生代的4/5,From和TO各占1/10。
  • 算法执行过程为:在进行Minor GC时,在对Eden区域的对象进行可达性分析之后,将存活对象移动到From Survivor并递增存活对象的年龄,如果某个对象的年龄超过了MaxTenuringThreshold,或者某个对象太大From Survivor无法存放,则将该对象移到到老年代。然后清空Eden区域,此时Eden区域和To Survivor区域都是空的,Minor GC完成,此时对下一次Minor GC来说,此次存放从Eden移动对象的From Survivor变成了To Survivor,空的To Survivor变成了From Survivor,即对应基于复制算法的Minor GC来说,每次Eden中存活的对象都是移动到From Survivor的。

老年代垃圾回收算法

  • 老年代垃圾回收主要是在进行Full GC时触发,触发Full GC主要包括四个:
  • 老年代空间不足:在新生代进行Minor GC之后还没有足够空间来存放新对象,将该新对象放到老年代,而老年代也没有足够空间来存放该对象时会触发老年代垃圾回收,即Full GC,此时同时对新生代和老年代进行垃圾回收;
  • 老年代空间不足:在进行Minor GC时,将对象从Eden移动到From Survivor,而From Survivor没有足够空间存放该对象,将该对象移动到老年代,而老年代也无法存放该对象,则触发Full GC;
  • 在Minor GC时晋升到老年代的对象的平均大小大于老年代当前的空闲空间时,也会触发Full GC。
  • 在程序中调用System.gc()函数时,默认也会进行Full GC,不过可以通过JVM参数:-XX:-+DisableExplicitGC 来禁用。
  • 老年代中主要存放年龄较大,即生命周期较长的对象,还有就是需要占用较大内存空间的对象,由于每次进行垃圾回收时,存活的对象通常较多,如果使用复制算法,首先需要复制大量对象,其次如果存活的对象太大,会From Survivor需要较大的内存空间。基于老年代对象的存活对象多,对象大的特点,所以不适合采用复制算法,否则会造成回收缓慢,造成应用停顿时间长。所以对老年代的垃圾回收通常采用标记压缩和标记清除算法,这两个算法都不需要借助额外的内存空间,如复制算法中的Survivor,提高了内存的使用率。

标记压缩算法和标记清除算法

  • 标记压缩和标记清除算法首先需要对老年代中的对象进行可达性分析并对可达(存活)对象进行标记,其中标记过程为从GC roots引用的对象开始,首先标记GC roots引用的对象为存活对象,然后从这些对象继续往下查找存活对象,如果某个对象存在一条从GC roots可达的路径则该对象是存活的,否则是需要被回收的垃圾对象;
  • 标记压缩和标记清除算法的不同之处为:标记压缩算法会将所有存活对象移到到一边,然后将边界以外的所有内存空间清空,从而减少老年代的内存碎片。而标记清除算法只是简单地将这些垃圾对象清除销毁,不会对老年代的内存空间进行压缩,故会存在内存碎片问题,但是由于不需要对存活对象进行移动操作,故标记清除算法执行速度较快。

3垃圾回收器

串行Serial垃圾回收器:-XX:+UseSerialGC

  • 串行垃圾回收器是单线程垃圾回收器,使用一个线程来执行Minor GC。串行垃圾回收器是运行在client模式的JVM进程的默认新生代垃圾回收器。在进行Minor GC时,需要暂停所有的应用程序线程。
  • JVM配置参数为:-XX:+UseSerialGC,使用该配置参数,新生代和老年代均使用串行垃圾回收器,其中老年代为基于标记压缩算法实现的Serial Old。

并行Parallel垃圾回收器:-XX:+UseParallelGC

  • 并行垃圾回收器是多线程版本的基于复制算法实现的垃圾回收器,使用多个线程同时进行垃圾回收。相对于单线程垃圾收集器,多个垃圾回收线程并行执行可以加快Minor GC的速度,减少应用停顿的时间。特别是对于包含多个CPU的服务器来说,一般使用并行垃圾回收器进行垃圾回收。
  • JVM配置参数为:-XX:+UseParallelGC,该配置参数只对新生代有效,即新生代使用并行垃圾回收器,老年代使用Serial Old串行回收器。这个也是运行在server模式的JVM进程的默认垃圾收集器配置,即新生代Parallel,老年代Serial Old。
  • 吞吐量优先:Parallel并行垃圾回收器除了提供多线程来执行垃圾回收外,其主要目的是提供高吞吐量,即应用程序执行时间占总执行时间的比例较高,其中吞吐量的计算为:吞吐量=应用程序执行时间 /(应用程序执行时间 + 垃圾回收器执行时间)。所以Parallel关注的是总的应用执行时间,而不是应用的单次响应速度,比较适合需要高CPU利用率的应用,如需要进行大量计算的后台任务,科学计算,保证这些任务尽快完成,而不是用户交互非常频繁且要求响应用户速度快的应用,如网络游戏,电商等web应用。
  • 吞吐量目标:Parallel垃圾回收器为了实现可控制的吞吐量,通过JVM参数:-XX:MaxGCPauseMillis来控制垃圾回收的最大停顿时间,-XX:GCTimeRatio直接控制吞吐量的大小。
  • 可控制吞吐量的实现:通过JVM参数:-XX:+UseAdaptiveSizePolicy来开启动态调整堆的大小来达到吞吐量控制目的,此时不需要配置堆的新生代,老年代的大小,如新生代大小-Xmn,Survivor大小-XX:SurvivorRatio,新生代晋升到老年代阀值-XX:PretenureSizeThreshold,只需要配置基本的堆配置,如最大大小-Xmx。通过JVM参数: -XX:ParallelGCThreads=20配置并行收集器的线程数,一般设置为和处理器数量相同。

并行ParNew垃圾回收器:-XX:+UseParNewGC

  • ParNew是串行Serial垃圾回收器的多线程版本,也是基于复制算法实现,主要和老年代的并行并发垃圾回收器CMS一起使用。
  • 与Parallel垃圾回收器不同的是,ParNew只是单纯的多线程版本的Serial垃圾收集器,并不具备可控的吞吐量和动态调整堆的新生代和老年代大小的功能。
  • 配置方式:如果老年代配置了使用CMS垃圾回收器,则新生代默认使用ParNew,不需要显示配置。如果需要显示配置,则JVM参数为:-XX:+UseParNewGC。其中ParNew和CMS的组合是响应时间优先的。如果年轻代的并行GC不想开启,可以通过设置-XX:-UseParNewGC来关掉。

串行Serial Old垃圾回收器:-XX:+UseSerialGC

  • Serial Old为老年代的垃圾回收器,是使用单线程的基于标记压缩算法实现的对老年代进行垃圾回收的。
  • JVM进程运行在client模式时,默认采用Serial Old作为老年代垃圾回收器。
  • 配置方式为:-XX:+UseSerialGC,此时老年代和新生代均使用串行垃圾回收器。
  • Serial Old垃圾回收器还作为CMS的一个后备垃圾回收器,即当使用CMS对老年代进行垃圾回收时,如果发生了Concurrent Mode Failure时,则降级为使用Serial Old对老年代进行垃圾回收。

并行Parallel Old垃圾回收器:-XX:+UseParallelOldGC

  • Parallel Old是一个多线程的基于标记压缩算法的老年代垃圾回收器。通常与新生代的并行Parallel垃圾回收器一起使用来实现可控的高吞吐量目的。
  • 当新生代使用:-XX:+UseParallelGC 开启时,老年代使用的还是Serial Old,故需要显示配置:-XX:+UseParallelOldGC来指定老年代使用并行Parallel Old垃圾回收器。

并行并发CMS垃圾回收器:-XX:+UseConcMarkSweepGC

G1垃圾回收器:-XX:+UseG1GC

  • G1垃圾回收器是更加智能的垃圾回收器,在实现层面,新生代和老年代在物理上的区分已经去除了,取而代之的是将堆划分为大小相同的一个个区域。不过在逻辑上仍属于分代回收,新生代和老年代由多个这种区域组成。
  • G1的设计规则就是可以通过简单明了的方式来进行性能调优,典型配置只需要如以下配置:指定堆的最大大小,指定GC的最大停顿时间,则G1垃圾收集器会想办法满足这个目标。如果我们需要调优,在内存大小一定的情况下,我们只需要修改最大暂停时间即可。

-XX:+UseG1GC -Xmx32g -XX:MaxGCPauseMillis=200

  • G1是JDK9的默认垃圾回收器。对于原有项目是否需要升级为G1,根据官方的建议是,如果当前项目使用CMS或者ParalleOldGC运行良好,并且没有因为GC问题导致长时间停顿,则建议保持现状,不需要升级为G1。如果存在以下情况,则可以尝试升级为G1,并可以基于GC日志来分析效果:
  • 实时数据占用了超过半数的堆空间
  • 对象分配率或者对象晋升速度变化明显
  • 期望消除耗时较长的停顿或GC(0.5s~1s)

标签:对象,新生代,回收,XX,GC,垃圾,参数
From: https://blog.51cto.com/u_16357390/8556627

相关文章

  • day03-4垃圾回收机制
    【垃圾回收机制】【一】引入解释器在执行到定义变量的语法时,会申请内存空间来存放变量的值,而内存的容量是有限的,这就涉及到变量值所占用内存空间的回收问题当一个变量值没有用了(简称垃圾)就应该将其占用的内存给回收掉,那什么样的变量值是没有用的呢?单从逻辑层面分析,我们......
  • MT6893_天玑 1200_5G芯片性能参数规格书datasheet_安卓核心板
    天玑1200(MT6893)是一款专为旗舰级5G芯片解决方案,具备令人惊叹的AI、相机和多媒体技术,为用户带来卓越的体验。采用先进的6纳米制程设计,内建各种先进技术,搭载旗舰级的八核CPU架构设计,支持高达16GB的强大四通道内存和双通道UFS3.1闪存,通过路径优化提供更快的应用程序......
  • 若依 vue前端 动态设置路由path不同参数 在页面容器里打开新页面(新路由),面包屑和标签页
    若依vue前端动态设置路由path不同参数在页面容器里打开新页面(新路由),面包屑和标签页标题根据参数动态改变,面包屑多级标题,侧边栏对应菜单亮起:https://blog.csdn.net/weixin_43991241/article/details/126319259?ops_request_misc=&request_id=&biz_id=102&utm_term=matched.redir......
  • JVM参数、配置项含义
    学习自:轻松永远记住经典jvm参数Jvm内存模型_jvm内存模型-CSDN博客JVM参数总结-简书有OutOfMemoryError有关的JVM参数_crash参数javajvm_毛发旺盛的程序员的博客-CSDN博客1、参数分类参数开头有四种:-、-X、-XX、-D javajvm.参数jvm参数-d_ctaxnews的技术博客_51CTO......
  • mysql 一些优化参数
     大批量数据加载优化load数据加载格式:loaddatalocalinfile'文件路径'intotable表名fieldsterminatedby'[分隔符]'lineterminatedby'[换行符]'11、首先,检测全局变量‘local_infile’的状态,如果是off状态则是不可用showglobalvariableslike'local_infile';......
  • Centos系统udp丢包&内核参数优化
    echo0>/proc/irq/31/smp_affinity_listecho1>/proc/irq/33/smp_affinity_list这两个命令是用于设置Linux中中断处理程序的亲和性,以提高系统的性能和稳定性。在Linux系统中,系统中断(IRQ)是由硬件触发的,它们通常被用于处理来自硬件设备的请求(例如,网络接口卡、磁盘控制器......
  • mapper中limit参数的问题
    通常情况下一般不会用limit进行分页操作,但是在数据量小的情况下使用limit还是挺好的,因为方便。在mapper中操作一般我们都是这样写,看起来没问题,但是跑起来会有问题。因为limit中不支持动态运算符,故在写分页的时候mapper.xml中以下这种写法是错误的://错误写法<selectid="queryPag......
  • 垃圾回收主要是回收那块内存区域?
    Java虚拟机的垃圾回收主要集中在Java堆这个内存区域。Java堆是用于存放对象实例的内存区域,垃圾回收的目标就是清理掉那些不再被引用的对象,释放内存空间,以便新的对象能够被创建和分配。Java堆可以划分为两个主要的区域:新生代(YoungGeneration):新创建的对象首先被分配到新生代。......
  • cocos creator新手入门教程:如何绑定参数到编辑器
    很多cocoscreator同学不知道如何绑定组件属性到编辑器上,今天我们来教大家如何绑定1:基本数据属性绑定到编辑器这个非常简单,模板是属性名字:默认的值;Is_debug:false,speed:100,2:系统组件类型与节点绑定到编辑器属性名字:{type:组件类型(cc.Sprite,cc.Label,cc.......
  • 如何利用拦截器获取HTTP请求参数
    在开发Web应用时,我们经常需要获取HTTP请求的参数。Spring框架提供了多种方式来获取这些参数,其中一种就是使用拦截器(Interceptor)。本文将详细介绍如何利用拦截器获取HTTP请求参数。1.拦截器简介在Spring框架中,拦截器是实现了HandlerInterceptor接口的类。拦截器可以在请求被处......