【jvm系列-10】深入理解jvm垃圾回收器的种类以及内部的执行原理

news2024/11/24 16:50:22

JVM系列整体栏目


内容链接地址
【一】初识虚拟机与java虚拟机https://blog.csdn.net/zhenghuishengq/article/details/129544460
【二】jvm的类加载子系统以及jclasslib的基本使用https://blog.csdn.net/zhenghuishengq/article/details/129610963
【三】运行时私有区域之虚拟机栈、程序计数器、本地方法栈https://blog.csdn.net/zhenghuishengq/article/details/129684076
【四】运行时数据区共享区域之堆、逃逸分析https://blog.csdn.net/zhenghuishengq/article/details/129796509
【五】运行时数据区共享区域之方法区、常量池https://blog.csdn.net/zhenghuishengq/article/details/129958466
【六】对象实例化、内存布局和访问定位https://blog.csdn.net/zhenghuishengq/article/details/130057210
【七】执行引擎,解释器、JIT即时编译器https://blog.csdn.net/zhenghuishengq/article/details/130088553
【八】精通String字符串底层机制https://blog.csdn.net/zhenghuishengq/article/details/130154453
【九】垃圾回收底层原理和算法以及JProfiler的基本使用https://blog.csdn.net/zhenghuishengq/article/details/130261481
【十】垃圾回收器的种类以及内部的执行原理https://blog.csdn.net/zhenghuishengq/article/details/130261481

深入理解jvm垃圾回收器的种类以及内部的执行原理

  • 一,jvm中的垃圾回收器
    • 1,垃圾回收器的概述
      • 1.1,吞吐量和暂停时间
      • 1.2,垃圾回收器的种类以及概述
    • 2,Serial垃圾回收器
    • 3,ParNew垃圾回收器
    • 4,Parallel垃圾回收器(高吞吐量)
    • 5,CMS垃圾回收器(低延迟)
      • 5.1,CMS处理器工作流程(重点)
      • 5.2,CMS采用标记清除算法的原因
      • 5.3,CMS回收器的优缺点以及可设置参数
    • 6,G1垃圾处理器(重点)
      • 6.1,G1垃圾回收器概述
      • 6.2,G1回收器的特点
      • 6.3,G1回收器的参数设置
      • 6.4,Region
      • 6.5,G1回收器回收垃圾的过程
      • 6.5,记忆集和写屏障
      • 6.6,G1垃圾回收详解
    • 7,经典垃圾回收器总结
    • 8,GC日志的常用参数

一,jvm中的垃圾回收器

1,垃圾回收器的概述

在《java虚拟机规范》中,并没有明确的对垃圾收集器做过多的规定,因此垃圾收集器可以是由任意产商,不同版本的JVM来实现。因此从不同角度来分析这个垃圾收集器,就可以将GC垃圾收集器分为不同的类型
在这里插入图片描述

如可以按照执行垃圾线程的线程数量来分类,可以分为串行垃圾回收器和并行垃圾回收器;也可以按照工作模式来区分,可以分为并发式垃圾回收器和独占式垃圾回收器;也可以按照碎片的处理方式区分,可以分为压缩式垃圾回收器和非压缩式垃圾回收器;也可以按照工作的内存区间分,可以分为年轻代回收器和老年代回收器

而在面对一款垃圾回收器的GC评估的时候,主要是从以下的几个方面很做出评价

  • 吞吐量:运行用户代码的时间占总运行时间的比例(总运行时间 = 程序运行的时间 + 垃圾回收的时间 )
  • 垃圾收集开销:垃圾收集所占总运行时间与总运行时间的比例
  • 暂停时间:执行垃圾收集时,程序的工作线程被暂停的时间(stw)
  • 收集频率:相对于应用程序的执行,收集操作发生的频率
  • 内存占用:Java堆区所占的内存大小。
  • 周期:一个对象从诞生到被回收所经历的时间

在这几个指标中,吞吐量、暂停时间和内存占用这三个指标又是重中之重。因为这三者每次只能满足其中的二者,吞吐量和这个暂停时间只能二选一

1.1,吞吐量和暂停时间

上面也提到了,这个吞吐量指的是CPU用于运行用户代码的时间与总CPU消耗时间的比值,即运行用户代码的时间/运行用户代码的时间 + 垃圾收集时间,如虚拟机总共运行了100分钟,垃圾收集花掉了1分钟,运行用户代码花掉了99分钟,那么其吞吐量就是 99 / 100 = 99%。

而注重吞吐量,则不需要考虑暂停时间的大小,如下图,在6s内,尽管上面的暂停时间是比较长,但是其暂停时间的占比是比较小的,因此可以认为更加的注重吞吐量,也可以认为注重吞吐量的垃圾收集器可以不用考虑这个stw的暂停时长

在这里插入图片描述

而注重低延迟的垃圾收集器,其吞吐量要低于上面这个,但是其延迟时间小,那么每次stw的时间就会更短,那么需要的空间也可以小一点。因此也可以证明上面的吞吐量和这个暂停时间是互为矛盾的。

高吞吐量的优点在于可以让应用程序始终感觉只有应用程序线程在做生产性工作,从直觉上来看,吞吐量越高程序运行的越快;低延迟的好处在于从整个流程来看,如果是因为某个应用导致被挂起一段时间始终是不友好的,因为200ms的stw暂停也可能会严重的影响到用户的体验,因此具有较低的暂停是很有必要的。因此,如果是一个交互式的应用程序,那么较低的延迟是优先选择,如剑圣一个q下去,你卡我几秒再掉血,那我不得把这游戏恨死。

如果优先选择吞吐量,那么比如会降低回收的执行频率,但是同时也会让stw的时间更长;如果优先选择低延迟,那么回收的频率增高,会导致新生代内存的缩减和程序吞吐量的下降

因此现在的垃圾回收器的标准是:在最大吞吐量优先的情况下,再降低停顿时间

1.2,垃圾回收器的种类以及概述

接下来通过这个垃圾收集器的历史,来详细说明一下垃圾收集器的种类。

  • 1999年,Serial GC横空出世,是第一款GC,以串行的方式运行
  • 2002年,Parallel GC和 CMS GC同时发布,以并行的方式运行,JDK6开始的默认GC
  • 2017年,JDK9中将G1变成默认的垃圾收集器,从而代替CMS
  • 2018年,JDK11发布,并且引入ZGC,可伸缩低延迟垃圾回收器
  • 2019年,JDK12发布,增强了这个G1,自动返回未用堆内存给操作系统
  • 2019年,JDK13发布,增强了ZGC,自动返回未用堆内存给操作系统
  • 2020年,JDK14发布,删除了CMS,CMS成为历史

而垃圾回收器的搭配使用如下,ParNew GC和这个CMS搭配使用,Parallel Scavenge GC和Parallel Old GC搭配使用,这个Serial GC和Serial Old GC搭配使用。在这三个组合中,前者都是用来回收新生代,后者都是用来回收老年代的垃圾,如下面的蓝色部分就是用来回收新生代,橙色部分就是用来回收老年代,而后面引进的G1垃圾回收器,既可以回收新生代,也可以回收老年代。

在这里插入图片描述

通过上面的垃圾收集器,得知有7款经典的垃圾回收器

  • 串行垃圾回收器:Serial、Serial Old
  • 并行回收器:ParNew 、 Parallel Scavenge 、Parallel Old
  • 并发回收器:CMS、 G1

在JDK8中,默认主要还是Parallel Scavenge + Parallel Old组合,或者是CMS + ParNew组合,如果是在C端,能够确认是单线程的环境下运行,那么也可以选择使用Serial + Serial Old组合。Parallel和ParNew的性能不相上下,但是由于框架的不兼容,导致只有这个ParNew可以和这个CMS组合,而这个Parallel不能和这个CMS组合。

查看当前默认的垃圾回收器的指令如下:

-XX:+PrintCommandLineFlags

或者通过命令的形式查看

//查看所有进程
jps
//通过进程号查看对应的信息
jinfo -flag UseParallel 进程号

2,Serial垃圾回收器

该回收器是最基本的,也是历史最悠久的串行垃圾回收器。

如下图详细的描述了Serial中的整个垃圾回收的执行流程。在新生代中,使用的是复制算法,如典型的s0区和s1区,并采用的是串行回收和stw机制的方式执行内存回收;在老年代中使用的是标记整理法,并且使用的是Serial搭配使用的Serial Old收集器,采用的也是是串行回收和stw机制。stw机制一般是在一个SafePoint的安全点的时候触发,并且此时会暂停所有的用户线程,从而执行垃圾回收线程

在这里插入图片描述

Serial Old主要有两个用途,一个是与新生代的Serial结合使用,一个是作为老年代CMS的替补方案。

Serial虽然是串行模式下的回收器,但是相对于其他的收集器而言,也有着其自身的优势。对于限定单个CPU而言,Serial收集器没有线程交互的开销,专心的做垃圾收集因此可以获取到最高的单线程效率。比如在用户桌面应用场景中,可用内存一般不大,可以在较短的时间内完成垃圾收集,只要垃圾收集的频率不要过于频繁,那么可以优先的选择这个串行的垃圾收集器。

在jvm虚拟机中,使用Serial收集器的参数如下

-XX:+UseSerialGC

也可以通过命令行的形式查看

//查看所有进程
jps
//通过进程号查看对应的信息
jinfo -flag UseSerialGC 进程号

而其缺点就是只能限定于单核CPU内运行,很难满足当代开发者们的需求。

3,ParNew垃圾回收器

Serial属于是单线程的垃圾回收器,而ParNew则是Serial的多线程版本,也就是说,ParNew除了可以采用并行回收的特性之外,其本质和Serial回收器无任何区别

ParNew收集器在新生代中也是采用的是并行模式,复制算法,使用到了stw机制,并且在很多的Server模式下,都是作为他们的默认垃圾收集器;但是在老年代中,可以搭配这个并发模式的CMS或者这个串行模式的Serial Old使用

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-K0Za7NGh-1682412834185)(img/1682307386705.png)]

对于新生代而言,其触发的GC次数频率会更高,回收的次数更加频繁,因此使用并行的方式执行,并采用空间换时间的复制算法来提高效率;对于老年代而言,GC的次数会更低,回收的次数更少,因此可以使用串行的方式,并采用更加平滑的标记整理法来节省资源。

在jvm虚拟机中,使用ParNew收集器的参数如下

-XX:+UseParNewGC

也可以通过命令行的形式查看

//查看所有进程
jps
//通过进程号查看对应的信息
jinfo -flag UseParNewGC 进程号

4,Parallel垃圾回收器(高吞吐量)

在HotSpot虚拟机中,Parallel在新生代和ParNew有着相同的特性,都是使用的是并行回收,以空间换时间的效率高的复制算法,以及对应的stw机制,不同的是ParNew仅有并行的特性,Parallel则在此基础上多加了一个 可控制的吞吐量 的特性,也被称为吞吐量优先的垃圾收集器。高吞吐量则可以高效率的利用CPU时间,尽快的完成运算任务,如批量处理,订单处理等。

和老年代中的 Parallel Old 结合使用,Parallel Old使用的算法是标记整理法,但同样也是基于并行回收和stw机制。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bM5FwmTB-1682412834186)(img/1682317043639.png)]

在吞吐量优先场景中,Parallel和Parallel Old收集器的组合可以优先考虑,此收集器在Java8中也是默认收集器。

在jvm虚拟机中,使用Parallel收集器的参数如下

-XX:+UseParallelGC          //手动指定新生代
-XX:+UseParallelOldGC       //手动指定老年代
-XX:ParallelGCThreads       //设置新生代并行收集器的数量,大小最好设置和cpu数量相等
-XX:MaxGCPauseMillis        //设置垃圾回收器最大的停顿时间
-XX:GCTimeRatio             //垃圾收集时间占总时间的比例
-XX:+UseAdaptiveSizePolicy  //手动指定老年代

也可以通过命令行的形式查看

//查看所有进程
jps
//通过进程号查看对应的信息
jinfo -flag UseParallelGC  进程号

5,CMS垃圾回收器(低延迟)

CMS:Concurrent-Mark-Sweep,第一款真正意义上的并发收集器,第一次实现了让垃圾收集线程与用户线程同时工作。CMS收集器关注的点是尽可能缩短垃圾收集时用户程序的停顿时间,也就是说,停顿的时间越短,就越适合与用户交互的程序,良好的响应速度可以提升用户体验。此垃圾回收采用的算法是标记清除法

5.1,CMS处理器工作流程(重点)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NnmWDDVZ-1682412834186)(img/1682321410352.png)]

通过上图可知,在CMS的工作流程主要分为四个阶段,分别是初始标记、并发标记、重新标记和并发清理

初始标记:在这个阶段中,程序的工作线程会因为stw机制而出现短暂的暂停,这个阶段的任务主要是标记出GC Root可以关联到的对象,一旦标记完成,就会恢复之前的状态。由于直接关联的对象比较小,因此这里的速度非常的块。

并发标记:从GC Roots的直接关联的对象开始遍历整个对象的过程,这个过程较长,但是不需要停顿用户线程,可以让用户线程和垃圾回收线程同时工作。

重新标记:由于在并发标记阶段中,工作线程和垃圾回收线程同时工作,难免会有新的垃圾出现或者旧的垃圾复活(finalize),因此需要做一次重新标记。此时会触发stw,需要消耗的时间稍长,但远比并发标记阶段时间短。

并发清除:此阶段是真正的清理掉标记阶段判断已死的对象,并且释放内存空间

尽管CMS收集器采用的是并发回收,但是其初始化标记和再次标记仍然会触发stw,不过暂停的时间不会太长。由于最费时的并发标记和并发清除都是并发执行,因此用户线程不需要暂停,从而让整体的垃圾回收是低延迟的。

CMS主要是用户回收老年代的对象,而用户线程和垃圾回收线程在同时工作,如果在内存满了再触发这个垃圾回收,那么这个用户线程就会运行不了,因此不能在内存满了的时候才触发垃圾回收工作,而是需要设置一个阈值,在达到阈值的时候就触发这个垃圾回收的工作。

5.2,CMS采用标记清除算法的原因

在目前的三种垃圾算法中,新生代一般使用复制算法,老年代一般使用标记整理法或者标记清除法,由于标记清除会产生大量的垃圾碎片,因此老年代一般优先选择使用标记整理法,那为啥这里会使用标记清除呢?

由于垃圾回收采用的是标记清除算法,因此可能会出现这个碎片化的问题,因此在分配内存的时候只能使用空闲列表的方式,而不能使用指针碰撞。主要是因为并发清理的时候,用户线程也在工作,即使标记整理法可以解决这个碎片化的问题,但是标记整理法会涉及到对象的移动问题,而用户线程正在工作,对象的地址是绝对不能发生改变的,因此这里只能选择标记清除算法,而不能选择标记整理算法。用户线程正在工作,你把人家地址给改变了,人家不得去告你。

如果一定要选择标记整理法,那么需要stw停止用户线程,这里为了低延迟,显然不可能在并发清理阶段出现stw

5.3,CMS回收器的优缺点以及可设置参数

CMS优点:实现了并发收集;低延迟

CMS缺点:采用的标记清除法,会产生垃圾碎片;对CPU资源敏感;并发标记可能出现新的垃圾,因此无法处理这种浮动垃圾

在jvm虚拟机中,使用CMS收集器的参数如下

-XX:+UseConcMarkSweepGC             //手动指定使用CMS收集器
-XX:CMSInitiatingOccupanyFraction   //设置堆内存使用率阈值,达到该阈值时触发垃圾回收
-XX:+UseCMSCompactAtFullColection   //指定FULL GC之后对内存空间进行整理
-XX:CMSFullGcsBeforeCompaction      //设置多少次FULL GC之后对内存空间进行整理
-XX:ParallelCMSThreads              //设置CMS线程的数量

因此通过这些垃圾回收器的优缺点可知,垃圾回收器的选择策略如下:想要最小化的使用内存和并行开销------Serial ,最大化应用程序的吞吐量------Parallel,最小化中断或者停顿时间------CMS

在JDK8中,CMS配合ParNew使用成为默认的垃圾回收器;在JDK14的版本中,CMS直接被移除不再使用,CMS成为历史。

6,G1垃圾处理器(重点)

6.1,G1垃圾回收器概述

从JDK9开始,使用的垃圾回收器就是G1回收器,被称为区域化分代式回收器。虽然已经有了高吞吐量的Parallel,以及低延迟的CMS,但是随着业务越来越大,复杂,以及用户越来越多,这两款处理器显然不能满足实际需求,并且随着内存的不断扩大和处理器的数量不断的增加,为了兼容高吞吐量和低延迟,使二者都可以满足需求,因此G1诞生。官方给G1设定的目标是:在延迟可控的情况下,尽可能的提高吞吐量。

G1是一个并行回收器,将堆内存分割为很多不相关区域,如Eden,s0,s1,老年代等。主动跟踪各个region,在每个region里面计算出其垃圾堆积的价值大小,然后在后台维护一个优先列表,每次根据允许的收集时间,优先回收价值最大的Region。就是说不管区域中总共对象的多少,而是哪个区域中的垃圾多,就优先回收哪个region区域,因此G1名字的由来-----Garbage First(垃圾优先)

6.2,G1回收器的特点

并行与并发:G1有并行性,可以在回收期间,有多个GC同时工作,此时会触发STW;也有并发性,可以与应用程序交替执行,不会触发stw,在整个阶段不会出现完全阻塞的情况。

分代收集:G1仍然属于分代收集器,他依然会去区分新生代和老年代,不同的是,堆中的对象不要求是连续的空间,也不需要固定其大小和数量。如下图,如果出现某个Eden区的所有对象被清除,那么那块地址下一次存储的就不一定是Eden区对象,可能是s区或者old区的对象。而在每个region中,只允许存在一种类型的对象。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5ZlgvA02-1682412834187)(img/1682389504407.png)]

空间整合:CMS采用的是标记清除算法,那么会产生内存碎片化问题。G1将内存划分为一个个小的region,内存的回收也是以region为单位的,其内部采用的是复制算法,整体可以看做成标记整理法,从而解决内存碎片化的问题,从而解决大对象不会因为无法找到连续内存空间而提前触发一次GC。

可预测的停顿时间模型:G1和CMS都是为了低延迟而诞生,G1除了追求低延迟之外,还可以建立一个可预测的停顿时间模型,能让使用者明确知道在一个长度为M的毫秒时间判断内,消耗在垃圾收集上不得超过N秒

6.3,G1回收器的参数设置

可以设置的参数如下

-XX:+UseG1Gc                    	//手动指定使用G1收集器
-XX:G1HeapRegionSize           		//设置region大小,值为2的幂
-XX:MaxGcPauseMillis                //设置最大GC停顿指标
-XX:ParallelGCThread                //设置stw工作线程的值
-XX:ConcGCThreads                   //设置并发标记的线程数
-XX:InitiatingHeapOccupancyPercent  //设置触发并发GC周期的Java堆占用阈值

G1的调优原则就是简化JVM的性能调优,开发人员只需要简单的三步就可以完成调优:开启G1垃圾收集器,设置最大的堆内存,设置最大的停顿时间

6.4,Region

在G1收集器中,它将整个Java堆划分成2048个独立大小的Region块,每个region块大小根据实际的大小而定,并且大小的值为2的幂次方,可以通过-XX:G1HeapRegionSize 来设置。在region中,不需要新生代和老年代逻辑连续。

如下图,一个region只能属于一个角色,E表示eden区,S表示Survivor区,O表示old区,空白部分表示未使用区域。同时在G1中,增加了一个Humongous内存区域,主要用于存储大对象,如果超过1.5个region,那么该对象存储在Humongous内存区域内,如果一个H区域存储不下,那么就会寻找一个连续的H区存储

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dxld8ypn-1682412834187)(img/1682389504407.png)]

6.5,G1回收器回收垃圾的过程

G1垃圾回收器和上面的垃圾回收器有着不同之处,上面的几款回收器主要是针对于新生代或者老年代的其中一个区域进行垃圾回收,而G1是即要对新生代进行垃圾回收,也要对老年代进行垃圾回收。G1的垃圾回收器主要包括三个环节:年轻代GC,老年代并发标记过程,回合回收

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-E543SGGl-1682412834188)(img/1682393777571.png)]

  • 当新生代的Eden区用尽时,就会开始触发年轻代的垃圾回收过程: G1的新生代收集阶段是一个并行的独占式的垃圾收集器。在新生代的回收期,G1 GC暂停所有的应用程序线程,启动多线程执行新生代回收。然后从新生代区间移动存活对象到s区或者老年代中。
  • 当堆内存达到45%的时候,就会触发老年代并发标记过程
  • 标记完成后开始混合回收的过程: 对于一个混合回收期,G1 GC从老年代区间将对象移动到空闲区间,这些空闲区间就成为了老年代的一部分。老年代回收器不需要将整个老年代回收,一次只需要扫描一部分老年代的区域即可。

6.5,记忆集和写屏障

在每个region中,region与region之间肯定存在相互引用,因此在region中,引入了这个Remember Set,被称为结果记忆集。每个记忆集中记录着引用着当前对象的对象地址,并且在写入记忆集时,被称为写屏障。并且在写入时,会有一个短暂的中断操作,回去判断写入的对象是否和当前类型的数据在不同的region,如果不同,那么就将相关引用的信息加载到Rset中,在进行垃圾回收时,则只需要扫描记忆集中的内容,而不需要进行全盘扫描。

如下图,每个Region区域都有对应的Rset记忆集, 如Region2区域,该区域被region1和region3所引用着,那么在region2区域对应的rset中,就会记录这个region1和region3的相关信息。如果Region2要被判断是否为垃圾并且进行回收的话,则只需通过这个Rset中记录的值即可缩小范围。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1M4ubSDP-1682412834188)(img/1682408274118.png)]

6.6,G1垃圾回收详解

新生代的回收过程如下:

  • 先扫描Root根,如一些静态对象,方法中的局部变量等,作为RSet的入口,
  • 然后再更新RSet,RSet可以准确的反映老年代对所在的内存分段中对象的引用,
  • 随后再处理这个RSet,老年代指向的Eden中的对象即为存活对象,
  • 随后再复制对象,将eden区的对象复制到s区或者old区,最后再去处理引用,如一些强、软、弱、虚引用等。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PUQiRiIP-1682412834189)(img/1682409311073.png)]

并发标记的过程如下:(该阶段和CMS阶段很类似)

  • 先是初始标记阶段,标记从根节点直接可达的对象,会触发stw;
  • 再是从根区域扫描,G1 GC扫描s区直接可达的老年代对象,并将这些对象标记;
  • 其次是并发标记,在整个堆中进行并发标记,若在该阶段中发现垃圾,那这个区域会立即被回收;
  • 接下来是再次标记的过程,修正上次标记的结果,此工程需要stw;
  • 再接下来是独占清理,计算各个区域的存活对象和GC的回收比例,会触发stw;
  • 最后是并发清理阶段,识别并清理完全空闲的区域。

混合回收的过程如下:

  • 采用复制算法,将新生代的垃圾和老年代的垃圾混合回收,老年代只有一部分,而不是全部的老年代。混合回收的算法个新生代中的回收算法完全一样,只是回收集多了老年代的内存分段。

因此在G1回收器中,需要避免使用-Xmn或者-XX:NewRatio等相关选项显式设置新生代大小,因为固定新生代会覆盖暂停时间的目标,并且堆暂停时间也不要过于苛刻

7,经典垃圾回收器总结

通过上面详细的对各种垃圾回收器的描述,因此将各个回收器的特点整理如下图
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EKAy8hCx-1682412834189)(img/1682411248279.png)]

垃圾回收器如何选择

1,优先调整堆的大小让服务器自己来选择
2,如果内存小于100M,使用串行收集器
3,如果是单核,并且没有停顿时间的要求,串行或JVM自己选择
4,如果允许停顿时间超过1秒,选择并行或者JVM自己选
5,如果响应时间最重要,并且不能超过1秒,使用并发收集器
6,4G以下可以用parallel,4-8G可以用ParNew+CMS,8G以上可以用G1,几百G以上用ZGC

8,GC日志的常用参数

-XX:+PrintGC                      //输出GC日志类
-XX:+PrintGCDetails               //输出Gc的详细信息
-XX:+PrintGCTimeStamps            //输出GC的时间戳
-XX:+PrintGCDateStamps            //输出Gc的时间戳
-XX:+PrintHeapAtGC                //在GC前后打印出堆信息
-Xloggc:../logs/gc.log            //设置日志的输出路径

如若转载,请附上转载链接地址:https://blog.csdn.net/zhenghuishengq/article/details/130369011

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/460367.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

JavaScript字符串操作

ASCII(as key) 字符集(了解) 我们都知道,计算机只能存储 0101010 这样的二进制数字,那么我们的 a ~ z / A ~ Z / $ / /… 之类的内容也有由二进制数字组成的 我们可以简单的理解为, a ~ z / …

浅谈文心一言

作者简介: 辭七七,目前大一,正在学习C/C,Java,Python等 作者主页: 七七的个人主页 文章收录专栏: 七七的闲谈 欢迎大家点赞 👍 收藏 ⭐ 加关注哦!💖&#x1f…

[oeasy]python0140_导入_import_from_as_namespace_

导入import 回忆上次内容 上次学习了 tryexcept 注意要点 半角冒号缩进输出错误信息 有错就报告 不要隐瞒否则找不到出错位置还可以用traceback把 系统报错信息原样输出 但是代码量好多啊 10多 行了 🤯可以把他输入部分和输出部分么?🤔 我…

【计算机组成原理】第四章 指令系统

系列文章目录 第一章 计算系统概论 第二章 运算方法和运算器 第三章 多层次的存储器 第四章 指令系统 第五章 中央处理器 第六章 总线系统 第七章 外围设备 第八章 输入输出系统 文章目录 系列文章目录前言第四章 指令系统4.1 指令系统的发展与性能要求4.1.1 指令系统的发展4…

CTR-GCN 代码理解

论文代码:https://github.com/Uason-Chen/CTR-GCN ctrgcn.py 文件路径:CTR-GCN/model/ctrgcn.py import math import pdbimport numpy as np import torch import torch.nn as nn from torch.autograd import Variabledef import_class(name):compone…

动态设置图片的主题色(保留明暗关系)

github地址 PrimaryColorDemo 效果 原始图片 就是一张普通的png图片 根据选择的主题色动态渲染。 思考 最近在思考怎么实现动态的设置图片的主题色。不是那种渲染透明iocn。而是把图片的明暗关系保留。而改变其中的主题色。终于花了半天的时间研究出来了。和大家共享。 …

AI对话AI才是正解?KAUST研究团队提出基于角色扮演的大模型交互代理框架CAMEL

电影《盗梦空间》中有这样一句非常经典的台词: “世上最具有可塑性的寄生虫是什么?是人类的想法。人类大脑中一个简单的想法,就可以建立一座庞大的城市。有时一个想法也可以改变世界,并改写一切规则,这就是我为什么要…

0703齐次方程-微分方程

文章目录 1 定义和解法1.1 定义1.2 微分方程中的变量替换1.3 齐次方程的解法 2 例题结语 1 定义和解法 1.1 定义 形式上可化为 d y d x g ( y x ) \frac{dy}{dx}g(\frac{y}{x}) dxdy​g(xy​)的方程,称为齐次方程。 例如 d y d x y x tan ⁡ y x , d y d x e y…

操作系统考试复习—第二章 2.1 2.2程序和进程的描述

第二章 进程的描述与控制 程序:有序的指令集合 程序顺序执行的特征:1.顺序性 2.封闭性 3.可再现性(确定性) 在多道程序环境下,允许多个程序并发执行,此时他们将失去封闭性,并具有间断性和不可再现性的特征。为此引…

net::ERR_CONTENT_LENGTH_MISMATCH 206 (Partial Content) 报错

一、问题描述 最近现场实施人员反馈有个功能不能正常使用,F12查看浏览器的控制台,提示net::ERR_CONTENT_LENGTH_MISMATCH 206 (Partial Content)的错误, HTTP状态码206表示“部分内容”(Partial Content),…

全网最细,Jmeter性能测试-分布式压力测试环境搭建(超详细)

目录:导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜) 前言 JMeter设计之初是…

【Redis】不卡壳的 Redis 学习之路:从十大数据类型开始入手

目录 类型 String 字符串 List 列表 Set 集合 Sorted Set /ZSet 有序集合 Hash 哈希表 GEO 地理空间 HyperLogLog 基数统计 Bitmap 位图 BitField 位域 Stream 流 线上测试地址 常用命令 key 操作指令 String 操作指令 List 操作指令 Set 操作指令 ZSet 操作…

STM32CubeMX | 使用STM32定时器的PWM输入模式测量脉冲宽度和周期

STM32CubeMX | 使用STM32定时器的PWM输入模式测量脉冲宽度和周期 目录 STM32CubeMX | 使用STM32定时器的PWM输入模式测量脉冲宽度和周期1、介绍2、STM32CubeMX配置2.1 基本配置2.2 PWM输出配置2.3 PWM输入捕获配置 3、程序修改和测试 本篇博客以STM32F103C8为例,其他…

selenium_交互 (谷歌浏览器驱动下载 xpath插件安装)

安装selenium (1)查看谷歌浏览器版本 谷歌浏览器右上角 ‐‐> 帮助 ‐‐> 关于 查看 浏览器版本: (2)操作谷歌浏览器驱动下载地址 http : // chromedriver . storage . googleapis . com / index . html 找到…

FPGA、 CPU、GPU、ASIC区别

一、为什么使用 FPGA? 众所周知,通用处理器(CPU)的摩尔定律已入暮年,而机器学习和 Web 服务的规模却在指数级增长。 人们使用定制硬件来加速常见的计算任务,然而日新月异的行业又要求这些定制的硬件可被重新…

2023第十四届蓝桥杯 C/C++大学生A组省赛 满分题解

写在前面 以下代码,目前均可通过民间OJ数据(dotcpp & New Online Judge), 两个OJ题目互补,能构成全集,可以到对应链接下搜题提交(感谢OJ对题目的支持) 如果发现任何问题&…

汽车制造数字化转型如何做?有哪些可行性案例?

引语:砥砺前行的先行者,为长期主义者带去曙光 国内制造企业亟需加速探索数字化转型之路。但是传统软件服务商提供的PLM、MES等系统已经无法满足企业个性化需求。通过传统软件服务商进行二次开发,成本高、周期长,难以适应迅速变化的…

少儿Python每日一题(25):岛屿问题

原题解答 本次的题目如下所示(题目来源:蓝桥杯): 编程实现: 有一片海域划分为N*M个方格,其中有些海域已被污染(用0表示),有些海域没被污染(用1表示)。请问这片N*M海域中有几块是没被污染的独立海域(没被污染的独立海域是指该块海域上下左右被已污染的海域包围,且…

【手把手做ROS2机器人系统开发六】创建用户自定义msg和srv文件

创建用户自定义msg和srv文件 目录 创建用户自定义msg和srv文件 一、程序编写 1、创建软件包 2、创建msg消息和srv服务文件夹 3、定义msg消息示例 4、定义srv服务示例 5、修改和添加编译选项 6、软件包设置 二、程序测试 1、编译软件包 2、测试查询信息 3、测试查询服务…

EasyCVR视频融合平台黑名单功能更新,防止设备恶意注册平台

为了防止别人恶意注册国标设备,EasyCVR视频融合平台也具备拦截设备注册的功能,即通过国标设备ID和注册IP地址进行拦截,也就是黑名单功能。 在3.1版本之前,黑名单的设置是在配置中心—平台接入中,在输入框中添加黑名单I…