HotSpot VM垃圾收集器——Serial Parallel CMS G1垃圾收集器的JVM参数、使用说明、GC分析

news2024/11/29 3:50:09

目录

    • HotspotVM的垃圾收集器简介
        • 1. Serial Collector
        • 2. Parallel Collector(throughput collector)
        • 3. Concurrent Mark Sweep Collector(CMS)
        • 4. Garbage-First Garbage Collector(G1)
        • 5. Z Garbage Collector(ZCG)JDK11
    • JVM参数设置——选择垃圾收集器的组合
        • 查看GC时用到的命令和JVM参数
        • 查看本机默认JVM信息
        • -XX:+UseSerialGC
        • -XX:+UseParallelGC
        • -XX:+UseParallelOldGC
        • -XX:+UseParNewGC
        • -XX:+UseConcMarkSweepGC
        • -XX:+UseG1GC
    • 总结
    • 参考


【JVM学习笔记】JVM内存区域定义与内存结构
【JVM学习笔记】对象的创建过程、 对象的内存布局、 如何定位和使用对象
【JVM学习笔记】内存回收与内存回收算法 就哪些地方需要回收、什么时候回收、如何回收三个问题进行分析和说明


HotspotVM的垃圾收集器简介

1. Serial Collector

Serial收集器是最基础、历史最悠久的收集器。由一个线程处理所有垃圾收集工作,单线程避免了静态条件,可能会相对的提高工作效率。在单线程处理器,或多线程处理器中需要处理少量数据集(100MB左右)时,有比较明显的优势。

  • Serail Young:Serial的新生代垃圾收集器,采用标记-复制算法 。
  • Serial Old:Serial的老年代垃圾收集器,采用标记-整理算法。

在这里插入图片描述



2. Parallel Collector(throughput collector)

是Serial的多线程版,由多线程执行垃圾收集工作,适合在多处理器中处理中大型数据集,特别是在新生代并发执行时,能显著的减少垃圾收集器的开销。

  • Parallel Young (ParNew):Parallel的新生代垃圾收集器,Serail Young的多线程版,它默认开启的收集线程数与处理器核心数量相同(-XX:ParallelGCThreads 可以限制收集线程数),侧重以多线程工作来降低暂停时长,采用标记-复制算法。
  • Parallel Young (PSYoungGen或称Parallel Scavenge):Parallel的新生代垃圾收集器,与ParNew不同,它是一个以吞吐量优先的并发垃圾收集器,侧重于吞吐量的控制(控制最大垃圾收集停顿时间:-XX:MaxGCPauseMillis、设置吞吐量大小:-XX:GCTimeRatio),采用标记-复制算法。
  • Parallel Old:Parallel的老年代垃圾收集器,Serial Old的多线程版,标记-整理算法。

在这里插入图片描述



3. Concurrent Mark Sweep Collector(CMS)

并发垃圾收集器,适合处理中大型数据集,甚至可以在程序允许时并发的处理大部分工作。这种收集器适用于需要更短暂停时长、对吞吐量要求不高的程序,不过它需要更多的处理器资源以快速处理垃圾收集工作。

  • CMS:用于老年代,采用标记-清除算法。 优点:并发收集、低停顿;缺点:需要更多的处理器资源、产生大量空间碎片等。CMS默认启动的回收线程数是(处理器核心数量+3)/4,核心越多占用CPU越少,但是当CPU小于四个时,它占用的处理器资源也就越大。
    在这里插入图片描述



4. Garbage-First Garbage Collector(G1)

G1是一种服务器端的并发垃圾收集器。与CMS相似,G1也适合处理中大型数据集,可以在程序允许时并发的处理大部分工作;不过G1收集器适用于具有大内存的多处理器机器,它在实现高吞吐量的同时,并能以高概率满足垃圾回收暂停时间目标。

  • G1:虽然它的目标是取代CMS收集器,但其实G1是一个跨代的垃圾收集器,它将会收集所有区域的内存,因此G1无法与其它收集器组合。关于G1的内存结构可以参考这篇。



5. Z Garbage Collector(ZCG)JDK11

暂时没有研究,有空了再回来看
参考:
11 The Z Garbage Collector
An Introduction to ZGC: A Scalable and Experimental Low-Latency JVM Garbage Collector





JVM参数设置——选择垃圾收集器的组合

由于内存分代的出现,每种垃圾收集器,对于不同分代的垃圾回收会分别使用不同的垃圾收集技术。而虚拟机针对不同的现实条件,还可以选用垃圾收集器的部分垃圾收集功能,从而达到不同收集器的组合功能。垃圾收集器也提供了相应的组合VM参数,以达到不同收集器的组合实现。

关于如何启动不同组合的JVM参数,参考后面的内容。

需要注意,如果不显式的表明使用了哪种收集器,在不同的CPU硬件、操作系统下,会有不同的默认收集器



查看GC时用到的命令和JVM参数

1. 查看当前机器上默认VM参数

java -XX:+PrintCommandLineFlags -version


2. 查看指定Java运行程序的JVM参数(如果设置了JVM参数,将会覆盖上面的默认值)

jinfo -flags <pid>
查询指定参数(options)设置:jinfo -flag <options> <pid>


3. 通过jmap查看用了哪种算法的收集器
jmap -heap <pid>
Windows:jmap -heap <pid> | findstr GC
Linux:jmap -heap <pid> | grep GC


4. 通过jcmd强制gc
jcmd <pid> GC.run
注:可以通过jcmd <pid>help来查看程序可以执行的命令


5. 启用GC日志,方便查看GC时使用了什么收集器和收集时的内存信息(JDK8,JDK9后使用-Xlog参数打印日志)

-XX:+PrintGC:打印GC时的基本信息
-XX:+PrintGCDetails:打印GC详细信息
-XX:+PrintHeapAtGC:打印GC前后的堆、方法区可用容量的变化
-XX:+PrintGCTimeStamps**:打印GC时间戳


已经启动的Java程序,可以通过下面的命令启用上述参数:
jinfo -flag +PrintGC <pid>



查看本机默认JVM信息

本机配置信息
内存:16GB
操作系统:WIN10 x64
JDK版本:1.8.0_171
VM:Java HotSpot™ 64-Bit Server VM

D:\Project>java -XX:+PrintCommandLineFlags -version
-XX:InitialHeapSize=257905728 -XX:MaxHeapSize=4126491648 -XX:+PrintCommandLineFlags 
-XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:-UseLargePagesIndividualAllocation 
-XX:+UseParallelGC
java version "1.8.0_171"
Java(TM) SE Runtime Environment (build 1.8.0_171-b11)
Java HotSpot(TM) 64-Bit Server VM (build 25.171-b11, mixed mode)



-XX:+UseSerialGC

启用组合:Serail Young (DefNew) + Serial Old Mark Sweep Compact

查看启用参数和GC内容:

D:\Project>jinfo -flag UseSerialGC 4288
-XX:+UseSerialGC

D:\Project>jmap -heap 4288 | findstr "GC"
Mark Sweep Compact GC

查看GC收集器详情:

D:\Project>jcmd 4288 GC.run
4288:
Command executed successfully


325.368: [Full GC (System.gc()) 325.368: 
	[Tenured: 32742K->32744K(349568K), 0.0769539 secs] 38309K->32744K(506816K), 
	[Metaspace: 57305K->57305K(1101824K)], 0.0770048 secs] 
[Times: user=0.08 sys=0.00, real=0.08 secs] 
  • Full GC (System.gc()):表明本次Full GC的原因是执行了System.gc()命令。

  • Tenured:老年代收集,一般表明老年代使用的是Serial Old收集器。

  • Metaspace:元空间收集情况,元空间为非堆,它是位于堆外的一块内存。

  • Times:本次GC所用时间。



-XX:+UseParallelGC

启用组合:Parallel Young (PSYoungGen、Parallel Scavenge) + Serial Old Mark Sweep Compact | Parallel Old Mark Sweep Compact

该JVM参数启用了Parallel Scavenge收集器,同时其老年代收集器默认为Parallel Old,可以通过设置参数来组合其它老年代的收集器。

查看启用参数和GC内容:

D:\Project>jinfo -flag UseParallelGC 15404
-XX:+UseParallelGC

D:\Project>jmap -heap 15404 | findstr "GC"
Parallel GC with 10 thread(s)

查看GC收集器详情:

D:\Project>jcmd 15404GC.run
15404:
Command executed successfully


76.217: [GC (System.gc()) 
	[PSYoungGen: 2870K->288K(140288K)] 35650K->33075K(489984K), 0.0026375 secs] 
[Times: user=0.00 sys=0.00, real=0.00 secs] 

76.220: 
[Full GC (System.gc()) 
	[PSYoungGen: 288K->0K(140288K)] 
	[ParOldGen: 32787K->31310K(349696K)] 33075K->31310K(489984K), 
	[Metaspace: 57241K->57241K(1101824K)], 0.0767850 secs] 
[Times: user=0.22 sys=0.00, real=0.08 secs] 



-XX:+UseParallelOldGC

启用组合:Serail Young (DefNew) | Parallel Young (PSYoungGen、Parallel Scavenge) | Parallel Young (ParNew)
+ Parallel Old Mark Sweep Compact

  • JDK 6时才提供Parallel Old收集器。
  • 该JVM参数,仅启用了Parallel Old收集器,新生代收集器会根据JVM默认参数来设置,也可以通过其它JVM参数指定新生代收集器。
  • 我的机器默认使用了UseParallelGC参数,所以新生代为PSYoungGen。

查看启用参数和GC内容:

D:\Project>jinfo -flag UseParallelOldGC 4964
-XX:+UseParallelOldGC

D:\Project>jmap -heap 4964 | findstr "GC"
Parallel GC with 10 thread(s)

查看GC收集器详情:

D:\Project>jcmd 4964 GC.run
4964:
Command executed successfully

675.850: [GC (System.gc()) 
	[PSYoungGen: 3065K->224K(141312K)] 29892K->27050K(491008K), 0.0026659 secs] 
[Times: user=0.00 sys=0.00, real=0.00 secs]

675.852: [Full GC (System.gc()) 
	[PSYoungGen: 224K->0K(141312K)] 
	[ParOldGen: 26826K->26795K(349696K)] 27050K->26795K(491008K), 
	[Metaspace: 56938K->56938K(1101824K)], 0.1212485 secs] 
[Times: user=0.27 sys=0.00, real=0.12 secs] 



-XX:+UseParNewGC

启用组合:Parallel Young (ParNew)
+ Serial Old Mark Sweep Compact | Parallel Old Mark Sweep Compact | Concurrent Mark Sweep (Old)

  • 除了Serial收集器外,目前只有它能与CMS收集器配合工作。
  • ParNew + CMS与ParNew + Serial Old组合,在JDK8被宣布废弃,JDK9取消了对该组合的支持。
  • -XX:+UseParNewGC参数也在JDK9后被直接取消了。

查看启用参数和GC内容:

D:\Project>jinfo -flag UseParNewGC 20052
-XX:+UseParNewGC

D:\Project>jmap -heap 20052 | findstr "GC"
Mark Sweep Compact GC

查看GC收集器详情(与serial别无二致,打印的GC日志都一样):

D:\Project>jcmd 20052 GC.run
20052:
Command executed successfully


16.495: [GC (Allocation Failure) 16.495: 
	[ParNew: 156622K->9790K(157248K), 0.0050190 secs] 213221K->66389K(506816K), 0.0050597 secs] 
[Times: user=0.00 sys=0.00, real=0.00 secs] 


89.628: [Full GC (System.gc()) 89.628: 
	[Tenured: 50767K->32723K(349568K), 0.0939450 secs] 83372K->32723K(506816K), 
	[Metaspace: 57211K->57211K(1101824K)], 0.0940025 secs] 
[Times: user=0.09 sys=0.00, real=0.09 secs] 

GC (Allocation Failure):表明本次GC的原因是内存分配失败导致的GC,从而进行的新生代垃圾收集(mirrorGC或称youngGC),如果GC后,内存仍无法分配就会尝试对堆进行扩容,如果已到堆的最大容量,那么将进行整堆收集。整堆收集后仍无法为对象分配内存时,就会抛出OOM异常。



-XX:+UseConcMarkSweepGC

启用组合:Serial Young (DefNew) | Parallel Young (ParNew) + Concurrent Mark Sweep (Old)

  • CMS的默认新生代为ParNew。
  • ParNew + CMS的组合在JDK8被宣布废弃,JDK9取消了对该组合的支持

查看启用参数和GC内容:

D:\Project>jinfo -flag UseConcMarkSweepGC 7156
-XX:+UseConcMarkSweepGC

D:\Project>jmap -heap 7156 | findstr "GC"
Concurrent Mark-Sweep GC

查看GC收集器详情:

D:\Project>jcmd 7156 GC.run
7156:
Command executed successfully

18.303: [GC (Allocation Failure) 18.303: 
	[ParNew: 153906K->13619K(157248K), 0.0094748 secs] 159600K->23724K(506816K), 0.0095149 secs] 
[Times: user=0.02 sys=0.00, real=0.01 secs] 


111.118: [Full GC (System.gc()) 111.118: 
	[CMS: 35564K->31991K(349568K), 0.0956757 secs] 37072K->31991K(506816K), 
	[Metaspace: 57246K->57246K(1101824K)], 0.0957642 secs] 
[Times: user=0.09 sys=0.00, real=0.10 secs]



-XX:+UseG1GC

启用G1收集器

查看启用参数和GC内容:

D:\Project>jinfo -flag UseG1GC 14300
-XX:+UseG1GC

D:\Project>jmap -heap 14300 | findstr "GC"
Garbage-First (G1) GC with 10 thread(s)

查看GC收集器详情:

D:\Project>jcmd 14300 GC.run
14300:
Command executed successfully

91.976: [Full GC (System.gc())  65M->31M(512M), 0.1022988 secs]
   [Eden: 23.0M(284.0M)->0.0B(307.0M) Survivors: 23.0M->0.0B Heap: 65.8M(512.0M)->31.6M(512.0M)], 
   [Metaspace: 57227K->57206K(1101824K)]
 [Times: user=0.11 sys=0.00, real=0.11 secs] 
  • Eden:新生代收集情况。

  • Survivors:幸存区收集情况。

  • Heap:整个堆空间收集情况。





总结

这一篇博客只是介绍了实际环境中,可能用到哪些收集器,并对这些收集器的优劣、组合关系做了分析,同时也分享了一些实际运行环境中可能用到的命令和参数。最后对如何启用收集器的组合参数做了一些说明。

有关每种收集器的详细内容并未做过多的分析,因为每一种收集器涉及的知识量都比较广,如果对某种收集器有浓厚的兴趣,可以参考这官网的收集器说明,里面详细的介绍了每种收集器的实现原理和具体参数设置等,也可以参考周志明作的深入理解Java虚拟机一书。





参考

深入理解Java虚拟机:JVM高级特性与最佳实践(第3版)周志明
java 8 doc
javase doc
Java HotSpot VM
memorymanagement
Java Virtual Machine Technology
Java Hotspot G1 GC的一些关键技术
Java HotSpot Equivalents of Exact VM Flags
Java Platform, Standard Edition Documentation
Java Platform, Standard Edition HotSpot Virtual Machine Garbage Collection Tuning Guide

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

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

相关文章

STM32实战总结:HAL之GUI

在TFT上简单的显示字符、数字、汉字、图形、图片等&#xff0c;都是一些简单的显示。如果想要进行较为复杂的显示&#xff0c;就推荐使用GUI。 市面上常见的嵌入式GUI有LVGL&#xff0c;emWin&#xff08;ucGUI&#xff09;&#xff0c;TouchGFX&#xff0c;Embedded GUI、QT f…

[附源码]计算机毕业设计springboot基于vuejs的爱宠用品销售app

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

ES系列二之常见问题解决

一 更新ES信息报错 报错信息如下&#xff1a;Use ElasticsearchException.getFailedDocuments() for detailed messages [{yjZ8D0oBElasticsearchException[Elasticsearch exception [typecluster_block_exception, reasonindex [au_report] blocked by: [FORBIDDEN/12/index …

c++ vector的模拟实现以及迭代器失效问题

目录 1.vector的模拟实现 2.迭代器失效问题 3.总结 1.vector的模拟实现 这里&#xff0c;我们使用三个指针来控制vector。 用_start指向头&#xff0c;_finish指向最后一个元素的尾巴&#xff0c;_end指向最大容量。 #include<iostream> #include<cassert>usin…

Spring Cloud Netfix Hystrix(断路器)

一、灾难性雪崩 造成灾难性雪崩效应的原因&#xff0c;可以简单归结为下述三种&#xff1a; 服务提供者&#xff08;Application Service&#xff09;不可用。如&#xff1a;硬件故障、程序BUG、缓存击穿、并发请求量过大等。 重试加大流量。如&#xff1a;用户重试、代码重试…

手记:把代码上传到Gitee等远程仓库的过程记录及常见问题

很久没用git了&#xff0c;指令都有点生疏了&#xff0c;今天上传了一些代码到码云上&#xff0c;先把过程记录下来供使用git的朋友参考。没有用图形化界面&#xff0c;因为只有熟悉指令才能真正的理解领会。 步骤一&#xff1a; 1、安装git&#xff1b;安装后可以使用指令git…

打造一个投资组合管理的金融强化学习环境

原创文章第120篇&#xff0c;专注“个人成长与财富自由、世界运作的逻辑&#xff0c; AI量化投资”。 今天继续金融强化学习环境。 网上的金融学习环境不少&#xff0c;但都太过于“业余”&#xff0c;或者离像样的投资还差得太远。我一直觉得投资组合应该是必要的&#xff0…

怎么恢复已删除的全部数据,不小心删除的数据怎么恢复,删除的文件还能找回吗

怎么恢复已删除的全部数据&#xff1f;一般来讲&#xff0c;当文件被删除后&#xff0c;都会暂时被放置在回收站的位置&#xff0c;如果我们想找回相应的丢失数据&#xff0c;具体该如何操作呢&#xff1f; 一、当回收站没有被清空 这是最简单的一种恢复误删数据的方法&#…

前端入门--JavaScript篇

JavaScript基础 文章目录JavaScript基础JavaScript是什么JavaScript的使用方式JavaScript的运行过程JS的语法三种语言的注释输入输出JS中的变量JS中基本的数据类型number类型string字符串undefined类型null类型运算符数组数组的创建数组的使用数组新增元素函数对象之前学过了HT…

缓存的设计

文章目录1. 缓存的更新机制1.1 被动更新1.2 主动更新1.2.1 Cache Aside Pattern &#xff08;更新数据库&#xff0c;再删除缓存&#xff09;1.2.2 更新数据库&#xff0c;更新缓存1.2.3 先删除缓存&#xff0c;在更新数据库1.3 Read/Write Through Pattern1.4 Write Behind Ca…

【Linux】权限管理

文章目录一、shell 命令以及运行原理二、Linux的用户权限1、权限概念引入2、用户分类3、用户切换4、用户提权三、Linux 权限管理1、文件访问者的角色划分2、文件类型和访问权限a、文件类型(后缀理解 file 指令讲解)b、文件访问权限四、文件访问权限的更改1、chmod 指令(对拥有…

STM32CubeMX串口通讯

串口的简单介绍 RS-232与TTL 根据通讯使用的电平标准不同&#xff0c;串口通讯可分为 TTL 标准及 RS-232 标准。而STM32的串口是TTL电平标准的。如果需要使用到RS-232则需要一个电平转换芯片。 单工通信、半双工通信和全双工通信 讲到串口&#xff0c;我们还需要具备这些基…

嵌入式分享合集113

一、 模拟输入信号的保护电路问题 四种模拟输入信号的保护电路的实现方法。 近由于工作的需要&#xff0c;涉及到了模拟输入信号的保护电路问题。结合以往的工作实践以及网络文献资料的查找。现在就保护电路作一简单的说明。 电源钳位保护 上述电路存在可靠性的问题。如果输…

JavaScript_DOM

JavaScript_DOM 概述 简单说就是用来操作HTML的方法&#xff0c;详情看官方文档。 对于我们只需要会使用下面的这个Element对象就可以了。 获取 Element对象 HTML 中的 Element 对象可以通过 Document 对象获取&#xff0c;而 Document 对象是通过 window 对象获取。 Doc…

焱融科技为国家重点实验室打造海量高性能存储

中国科学院大气物理研究所大气科学和地球流体力学数值模拟国家重点实验室&#xff08;英文缩写 LASG&#xff09;是国家级重点实验室。LASG 主要研究方向为地球气候系统模式的研发与应用&#xff1b;天气气候动力学理论、气候系统变化规律及其异常发生机制&#xff1b;天气气候…

排行榜谁最稳?

在 RedMonk 编程语言排行榜中&#xff0c;前端JavaScript 编程语言从2015年开始便稳居榜首&#xff0c;可以说是所有编程语言中最稳定的一个。 01 JavaScript 常年居于榜首原因 JavaScript 编程语言可以常年居于排行榜榜首位置&#xff0c;和它是前端工程师使用的唯一编程语言…

【树莓派】刷机、基础配置及多种方式登录

目录一、树莓派刷机二、树莓派登录1、HDMI线连接显示器登录2、串口方式登录&#xff08;1&#xff09;USB-TTL模块连接树莓派串口&#xff08;2&#xff09;修改系统配置&#xff0c;启用串口&#xff08;3&#xff09;用secureCRT登录树莓派3、网络方式登录&#xff08;1&…

基于51单片机霍尔传感器测速(仿真+源程序)

资料编号&#xff1a;196 下面是该资料仿真演示视频&#xff1a; 196-基于51单片机霍尔传感器测速&#xff08;仿真源程序全套资料&#xff09;功能简介&#xff1a; 51单片机计数测速转速测量&#xff0c;在仿真中等价于测量外部脉冲频率&#xff1b;如果修改输入脉冲的频率&…

前端小白科普:小程序组件与插件有啥区别?怎么用?

一直以为小程序组件和小程序插件是一回事&#xff0c;只是措辞不一样&#xff0c;导致造成乌龙&#xff0c;其实完全是两回事&#xff0c;插件是可以直接提供服务的&#xff0c;组件是给开发者提供的轮子&#xff0c;不能直接提供服务。 先看看微信是如何定义小程序插件的&…

[附源码]计算机毕业设计springboot健身房信息管理

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…