JVM之选择合适的垃圾收集器(CMS、G1)

这篇具有很好参考价值的文章主要介绍了JVM之选择合适的垃圾收集器(CMS、G1)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

JDK1.8为例:

1.JVM(Java Virtual Machine)是用于运行Java字节码的虚拟机,Java虚拟机包括一个类加载器子系统(Class Loader SubSystem)、运行时数据区(Runtime Data Area)、执行引擎和本地接口库(Native Interface Library)。本地接口库通过调用本地方法库(Native Method Library)与操作系统交互

运行时数据区是JVM参数调优的主要区域,有栈、程序计数器、堆、方法区-元空间、本地方法区,除程序计数器外其他区域都能进行垃圾收集
JVM之选择合适的垃圾收集器(CMS、G1),java,jvm,java,开发语言

2.栈,它的生命周期与线程相同,线程私有,会使用操作系统原生内存,方法内的局部变量、对象引用等,使用的内存会随着方法执行完,线程销毁而被操作系统回收,栈内存默认1M,JVM通过 -Xss256k 命令设置大小,.栈设置的越大,允许的栈深度越深(如递归),如果线程请求的栈深度大于虚拟机所允许的深度,将抛出StackOverflowError异常

3.本地方法栈是执行本地Native方法的相关的区域

4.程序计数器,保存代码执行位置,CPU下次再次执行时会从保存的位置处往下执行

5.方法区(元空间)用来存储类型的元数据信息,如:存储常量、静态变量、类信息、字段信息、方法名、方法代码、方法返回类型、常量池、JIT即时编译后的机器码等数据,在Java 8中,JVM将类的元数据放入本地内存(Native Memory)中,将常量池和类的静态变量放入Java堆中,这样JVM能够加载多少元数据信息就不再由JVM的最大可用内存(MaxPermSize)空间决定,而由操作系统的实际可用内存空间决定。

6.堆,JVM最大内存区域,参数调优主要是该区域,虚拟机把堆内存按 分代 模型划分 新生代、老年代

6.1.新生代中的对象大多数都符合“朝生夕灭”,使用Young GC 往往能快速清理掉大部分垃圾,留下来的会在Survivor1与Survivor2直接来回拷贝,并增加对象的年龄,达到年龄的和大对象一起放到老年代

6.2.老年代存放新生代中多次未被回收的对象和大对象, 使用 Full GC,(1.每次Young GC之前会进行一些判断,看看是否需要老年代先进行一下Full GC,2.Young GC之后,存活对象Survivor区放不下,老年代也放不下了,那么触发一次Full GC)如果收集后还无法申请到内存,则会抛出OutOffMemoryError

6.3.垃圾对象判定标准:1.引用计数法(2个类互相引用时无法释放),2.可达性分析算法(JVM使用此方法)

6.4.垃圾回收算法:堆内存中,JVM根据不同年代(或JDK版本),使用不同垃圾回收算法

  • 标记-清除:标记出垃圾对象,直接清楚掉,会有内存碎片
  • 复制:复制算法速度快,内存使用率不高,新生代回收后只保留少量存活对象,复制到Survivor区
  • 标记-整理:标记所有可达对象,完成后未被标记的对象将会被清理掉,然后将所有存活的对象压缩到内存的一端,标记-整理算法解决复制算法内存减半的高额代价问题

6.5.JVM垃圾回收算法

  • Serial垃圾收集器:单线程回收,进行 Young GC 和 Full GC时所有的应用线程都会被暂停,适用于32位小型机小内存环境,使用 -XX:+UseSerialGC
  • ParallelGC垃圾收集器:多线程回收,进行 Young GC 和 Full GC时所有的应用线程都会被暂停,JDK 7u4 及之后版本的默认该收集器,使用 -XX:+UseParallelGC -XX:+UseParallelOldGC显示指定(前者是收集新生代、后者是收集老年代)
  • CMS收集器:多线程回收,进行 Young GC时所有的应用线程都会被暂停,Full GC 时不再暂停应用线程,(使用多个后台线程收集老年代,付出的代价是更高的 CPU 使用),JDK8中CMS收集器默认是关闭的,使用 -XX:+UseParNewGC -XX:+UseConcMarkSweepGC 显示开启(前者是收集新生代、后者是收集老年代)
  • G1垃圾收集器:多线程回收,新生代的垃圾收集仍然采用暂停所有应用线程,它把整个堆分成了2048个小区域,独立使用这些区域的内存资源并且跟踪这些区域的垃圾收集进度,同时在后台维护一个优先级列表,在垃圾回收过程中根据系统允许的最长垃圾收集时间,优先回收垃圾最多的区域,JDK8中使用 -XX:+UseG1GC 开启
  • ZGC垃圾收集器 :JDK11中可使用的回收算法,在G1上进行了多项优化,使用XX:+UnlockExperimentalVMOptions -XX:+UseZGC ,可以参考腾讯开源的Tencent Kona JDK11

6.6.怎么选择垃圾回收算法,建议如下:

  • CPU核心少,内存1-2GB的,使用JDK默认的收集器即可
  • CPU核心大于4,内存4-6GB的,使用CMS垃圾收集器: ‐XX:+UseParNewGC -XX:+UseConcMarkSweepGC
  • CPU核心大于8,内存6-32GB的,使用G1垃圾收集器: ‐XX:+UseG1GC

与CPU有关是因为CMS、G1都会开启多个后台线程来收集垃圾,如果CPU核心不够,会造成CPU资源竞争、退化为单线程收集,性能更慢

6.7.JVM关键参数设置:

  • 默认启动:java -jar xxx.jar
  • 设置最大内存启动:java -jar -Xms2g -Xmx2g xxx.jar
  • 设置新生代启动:java -jar -Xms4g -Xmx4g -Xmn1g xxx.jar
  • 使用CMS收集器启动:java -jar -Xms6g -Xmx6g ‐XX:+UseParNewGC -XX:+UseConcMarkSweepGC xxx.jar
  • 使用G1收集器启动:java -jar -Xms16g -Xmx16g ‐XX:+UseG1GC -XX:MaxGCPauseMillis=120 -XX:ParallelGCThreads=8 xxx.jar
预期停顿时间是120ms:-XX:MaxGCPauseMillis=120
垃圾收集线程数:-XX:ParallelGCThreads= N ,N = 8 + ((N - 8) * 5 / 8), N代表CPU 的数目
如果服务器上有多个JVM实例,则需要调整ParallelGCThreads数量,过多的线程数会导致争抢CPU资源,ParallelGCThreads = min(CPU数量/JVM实例数, 8+((N-8)*5/8))

更多其他参数请自行查阅

7.直接内存,NIO相关类使用了直接内存,避免数据在内核与JVM之间来回拷贝

8.JVM工具

 1.jps 查看java进程
 2.jstat 虚拟机统计工具
  jstat -gcutil 2764
   S0    S1   E    O     M    YGC YGCT FGC FGCT   GCT
   0.00 0.00 6.20 41.42 47.20 16 0.105 3   0.472 0.577
   E表示新生代Eden区使用了6.2%的空间,2个S0、S1表示Survivor0、Survivor1,老年代(O,表示Old)和元空间(M)则分别使用了41.42%和47.20%的空间。
   程序运行以来共发生Minor GC(YGC,表示YoungGC)16次,总耗时0.105秒;发生Full GC(FGC,表示Full GC)3次,总耗时(FGCT,表示Full GCTime)为0.472秒;
   所有GC总耗时(GCT,表示GC Time)为0.577秒
   
 3.jinfo 实时查看和调整虚拟机各项参数, jinfo pid
 4.jmap 用于生成堆转储快照dump文件,jmap pid ,jmap -dump:format=b,file=zy.bin 30790
 5.jhat 分析jmap生成的快照文件,jhat zy.bin (一般使用VisualVM,不用此命令工具)
 6.jstack 用来查看线程停顿情况,jstack [option] pid ,jstack -l 30790,option有 -F(当正常请求不被响应时,强制输出线程堆栈),-l(除堆栈外还输出锁信息),-m(可以显示c/c++本地方法堆栈)
 7.VisualVM https://visualvm.github.io
 8.JVM参数调优可以应用到eclipse或Idea,如:
   -XX:+UseParNewGC
   -XX:+UseConcMarkSweepGC
   或单独使用-XX:+UseG1GC

 9.查看JVM运行时长:jcmd process_id VM.uptime
 10.查看JVM属性:jcmd process_id VM.system_properties 或 jinfo -sysprops process_id
 11.获取JVM版本:jcmd process_id VM.version
 12.查看JVM内存:jinfo -flags process_id
 13.查看每个线程栈信息:jstack process_id

以上是个人学习JVM知识和日常工作中的理解,如有错误,请包含与留言指正文章来源地址https://www.toymoban.com/news/detail-730498.html

到了这里,关于JVM之选择合适的垃圾收集器(CMS、G1)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • CMS垃圾收集器&三色标记-JVM(十二)

    上篇文章说了CMS垃圾收集器是赋值清除,所以他不可以碎片整理,于是jvm支持两个参数,几次fullGC之后碎片整理压缩空间。Cms他会抢占cpu资源,因为是并行运行,所以会有浮动垃圾。还有执行不确定性,垃圾收集完,继续进入新的对象,导致异常concurrent mode faliture,最后用

    2024年02月16日
    浏览(37)
  • 深入理解JAVA垃圾收集器CMS,G1工作流程原理 GC流程图 什么社会触发Minor GC?触发MinorGC过程。Full GC 过程。

    JVM内存空间基础知识点(基于JDk1.8) 1.方法区:逻辑概念,元空间,方法区主要用于存储类的信息、常量池、方法数据、方法代码等。方法区逻辑上属于堆的一部分,但是为了与堆进行区分,通常又叫“非堆”。 2.程序计数器:程序计数器可以看作当前线程所执行的字节码的

    2024年04月25日
    浏览(39)
  • JVM(Java Virtual Machine)G1收集器篇

    本文参考《深入理解Java虚拟机》,本文主要介绍G1收集器的收集思想和具体过程(填上一篇文章留下的坑) 本系列其他文章链接: JVM(Java Virtual Machine)内存模型篇 JVM(Java Virtual Machine)垃圾收集算法篇 JVM(Java Virtual Machine)垃圾收集器篇 G1是一款主要面向服务端应用的垃圾

    2024年02月07日
    浏览(39)
  • 详细了解G1、了解G1、G1垃圾收集器详解、G1垃圾回收器简单调优

    4.详细了解G1: 4.1.一:什么是垃圾回收 4.2.了解G1 4.3.G1 Yong GC 4.4.G1 Mix GC 4.5.三色标记算法 4.6.调优实践 5.G1垃圾收集器详解 5.1.G1垃圾收集器 5.2.G1的堆内存划分 5.3.G1的运行过程 5.4.三色标记 5.4.1.漏标问题 5.5.记忆集与卡表 5.6.安全点与安全区域 6.G1垃圾回收器简单调优 6.1.堆 6.2

    2024年02月11日
    浏览(41)
  • 从原理聊JVM(二):从串行收集器到分区收集开创者G1

    作者:京东科技 康志兴 随着Java的进化过程,涌现出各种不同的垃圾回收器,从串行执行到并行执行,从高吞吐到低延迟,终极目标就是让开发人员专注于程序的代码书写而无需关注内存管理。 JDK早期出现的垃圾回收器通常单独作用于不同分代,到后期出现的G1开始,才可以

    2023年04月24日
    浏览(34)
  • 【JVM】JVM垃圾收集器

    垃圾收集器是负责 执行垃圾回收的组件 ,它们用于 管理Java程序运行时的内存分配和释放 。垃圾收集器的主要任务是 自动回收不再使用的内存对象 ,并将 内存空间重新回收 以供程序继续使用。 Serial和Serial Old串行垃圾收集器,是指 使用单线程进行垃圾回收 ,堆内存较小,

    2024年02月13日
    浏览(41)
  • JVM 垃圾收集器

    重点:CMS,G1,ZGC 主要垃圾收集器如下,图中标出了它们的工作区域、垃圾收集算法,以及配合关系。 Serial 收集器 Serial 收集器是最基础、历史最悠久的收集器。 如同它的名字(串行),它是一个单线程工作的收集器,使用一个处理器或一条收集线程去完成垃圾收集工作。

    2024年02月10日
    浏览(45)
  • Java虚拟机(JVM)垃圾收集器、新生代、老年代、永久代以及内存分配策略

    在 Java 中,堆被划分成两个不同的区域:新生代 ( Young )、老年代 ( Old )。而新生代 ( Young ) 又被划分为三个区域:Eden、From Survivor、To Survivor。这样划分的目的是为了使 JVM 能够更好的管理堆内存中的对象,包括内存的分配以及回收。 新生代中一般保存新出现的对象,所以每次

    2024年02月04日
    浏览(80)
  • JVM的故事——垃圾收集器

    新生代收集器,最基础的收集器,单线程。进行垃圾收集时必须暂停其他所有工作线程,stop the world 新生代收集器,实质上是serial收集器的多线程版本。除了serial,只有它能和CMS收集器(老年代收集器)配合工作。随着处理器核心数越来越多,parnew比serial有着更好的性能。(但如

    2024年02月10日
    浏览(48)
  • 深入理解JVM垃圾收集器

    相关系列 深入理解JVM垃圾收集算法-CSDN博客 目前市面常见的垃圾收集器有Serial、ParNew、Parallel、CMS、Serial Old、Parallel Old、G1、ZGC以及有二种不常见的Epsilon、Shenandoah的,从上图可以看到有连线的的垃圾收集器是可以组合使用,是年轻代+老年代。为什么会出现这么多的垃圾收集

    2024年04月09日
    浏览(48)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包