• JVM调优理论与实践最佳结合


    目录

    一、GC介绍

    1.什么是垃圾

    2.如何定位垃圾

    3.常见的垃圾回收算法

    4.JVM内存分代模型(用于分代垃圾回收算法)

    5.常用的垃圾收集器

    Serial

    Serial Old

    Parsllel Scavenge

    Parallel Old

    CMS

    ParNew

    G1

    二、调用工具

    1.常见调优命令

    jps:虚拟机进程状况工具

    jstat(JVM statistice Monitoring Tool):虚拟机统计信息监视工具

    jinfo(Configuration Info for Java):java配置信息工具

    jmap(Memory Map for Java):java内存影响工具

    jstack(java堆栈跟踪工具)

    2.可视化工具

    JConsole:java监视与管理控制台

    VisualVM是功能强大的运行监视和故障处理软件之一。可以安装很多插件,集成很多功能。

     arthas:是 Alibaba 开源的 Java 诊断工具,非常好用

    三、JVM调优策略

    1.选择合适的垃圾回收器

    2.调整内存大小

    3.调整大对象的标准

    4.调整GC的触发时机

    5.更多调优策略


    一、GC介绍

    1.什么是垃圾

    垃圾的定义:没有任何引用指向的一个对象或者多个对象(循环引用)

    2.如何定位垃圾

    引用计数(ReferenceCount)内存上有一块空间记录被引用的次数

    根可达算法(RootSearching)

    3.常见的垃圾回收算法

    标记清除(mark sweep) - 位置不连续 产生碎片 效率偏低(两遍扫描)

    拷贝算法 (copying) - 没有碎片,浪费内存空间

    标记压缩(mark compact) - 没有碎片,效率偏低(两遍扫描,指针需要调整)

    4.JVM内存分代模型(用于分代垃圾回收算法)

    5.常用的垃圾收集器

    Serial

    Serial是历史比较久远、方式比较直接的收集器。它是一个单线程工作的收集器,在Serial工作期间要停止所有的业务线程(STW),等待Serial工作完毕,业务线程再开始工作。

    使用标记-复制算法收集新生代垃圾。

    在这里插入图片描述

    Serial Old

    Serial Old是Serial 收集器的老年代版本,它同样是一个单线程收集器,使用标记-整理算法。

    同样是在工作期间,停止所有业务线程。

    在这里插入图片描述

    Parsllel Scavenge

    Parsllel Scavenge是新生代的垃圾收集器,采用标记-复制算法。但是他是一个多线程的,其它收集器目标是尽可能缩短垃圾收集时用户线程的停顿时间,而它的目标是提高吞吐量(吞吐量 = 运行用户程序的时间 / (运行用户程序的时间 + 垃圾收集的时间))。

    在这里插入图片描述

    Parallel Old

    Parallel Old收集器是Parallel Scavenge收集器的老年代版本,支持多线程并行收集。采用标记-整理算法实现。

    Parsllel Scavenge与Parallel Old是JDK1.8版本默认的垃圾收集器

    在这里插入图片描述

    CMS

    CMS(Concurrent Mark Sweep),收集器几乎占据着 JVM 老年代收集器的半壁江山,它划时代的意义就在于垃圾回收线程几乎能做到与用户线程同时工作。

    使用标记-清除算法收集老年代垃圾。

    工作流程主要有如下 4 个步骤:

    • 初始标记: 仅仅只是标记一下 GC Roots 能直接关联到的对象,速度很快,需要停顿(Stop-the-world)
    • 并发标记: 进行 GC Roots Tracing 的过程,它在整个回收过程中耗时最长,不需要停顿
    • 重新标记: 为了修正并发标记期间因用户程序继续运作而导致标记产生变动的那一部分对象的标记记录,需要停顿(Stop-the-world)
    • 并发清除: 清理垃圾,不需要停顿

    在整个过程中耗时最长的并发标记和并发清除过程中,收集器线程都可以与用户线程一起工作,不需要进行停顿

    在这里插入图片描述

    ParNew

    工作在新生代,本质为Serial收集器的多线程版本,采用“复制算法”;只有它能与CMS收集器配合工作

    G1

    该收集器可以算得上是垃圾收集器技术发展历史上里程碑式的成果。我们之前聊的垃圾收集器,垃圾收集的目标要么是针对整个老年代(Major GC),要么就是针对整个新生代(Minor GC),要么就好似整个Java堆进行回收(Full GC)。但是G1则提出了另一种内存布局形式–基于Region的内存布局形式。当然这种内存布局形式也是基于分代理论设计的,但是它不再坚持固定大小以及固定数量的分代区域划分,而是将连续的Java堆划分为多个大小相等的独立区域(Region),每一个Region都可以扮演新生代的Eden空间,Survivor空间,或者老年代空间。当然对于一个超过了Region容量一半的对象,会被判定为大对象,将会用特殊的Humongous来进行存储,如果对象过大则会存储在连续的Humongous中,G1的大多数行为会将Humongous区域当作老年代来看待。

    使用复制 + 标记 - 整理算法收集新生代和老年代垃圾。

    G1 把堆划分成多个大小相等的独立区域(Region),新生代和老年代不再物理隔离。

    二、调用工具

    调优第一种:在业务正常使用的情况下,重启(做好负载)

    调优第二种:换垃圾回收器

    调优第三种:看日志、使用工具、排查问题、优化逻辑

    1.常见调优命令

    jps:虚拟机进程状况工具

    选项作用
    -q只输出LVMID,省略主类名称
    -m输出虚拟机进程启动是传递给主类main()函数的参数
    -l输出主类名
    -v输出虚拟机进程启动时JVM参数
    1. [admin@d-metaverse ~]$ jps -l
    2. 8611 /home/admin/metaverse-backend-dev/metaverse-provider-cim-1.0-SNAPSHOT.jar
    3. 9572 /home/admin/metaverse-backend-dev/metaverse-provider-login-1.0-SNAPSHOT.jar
    4. 1797 /home/admin/metaverse-backend-dev/metaverse-provider-stepbar-1.0-SNAPSHOT.jar
    5. 8421 /home/admin/metaverse-backend-dev/metaverse-gateway-1.0-SNAPSHOT.jar
    6. 8268 /home/admin/metaverse-backend-dev/metaverse-provider-timing-1.0-SNAPSHOT.jar
    7. 9933 /home/admin/metaverse-backend-dev/metaverse-provider-course-1.0-SNAPSHOT.jar
    8. 8879 /home/admin/metaverse-backend-dev/metaverse-provider-activity-1.0-SNAPSHOT.jar
    9. 9746 /home/admin/metaverse-backend-dev/metaverse-provider-subassembly-1.0-SNAPSHOT.jar
    10. 10258 /home/admin/metaverse-backend-dev/metaverse-provider-pushclass-1.0-SNAPSHOT.jar
    11. 10067 /home/admin/metaverse-backend-dev/metaverse-provider-synchronization-1.0-SNAPSHOT.jar
    12. 9018 /home/admin/metaverse-backend-dev/metaverse-provider-fileupload-1.0-SNAPSHOT.jar
    13. 9338 /home/admin/metaverse-backend-dev/metaverse-provider-chapter-1.0-SNAPSHOT.jar
    14. 11771 jdk.jcmd/sun.tools.jps.Jps
    15. 11518 /home/admin/metaverse-backend-dev/metaverse-provider-class-1.0-SNAPSHOT.jar

    jstat(JVM statistice Monitoring Tool):虚拟机统计信息监视工具

    选项作用
    -class监视类加载、下载数量、总空间等
    -gcutil 与-gc 输出一直,主要关注已使用空间占总空间的占比
    -gc监视堆状况,包括Eden、Survivor、老年代、永久代等
    1. [admin@t-points ~]$ jstat -class 1351
    2. Loaded Bytes Unloaded Bytes Time
    3. 13693 25173.1 0 0.0 74.57
    4. [admin@t-points ~]$ jstat -gc 1351
    5. S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT
    6. 7168.0 8704.0 6240.0 0.0 157184.0 78732.0 349696.0 41656.1 76720.0 73530.4 9904.0 9255.2 28 1.486 3 1.485 2.971
    7. [admin@t-points ~]$ jstat -gcutil 1351
    8. S0 S1 E O M CCS YGC YGCT FGC FGCT GCT
    9. 87.05 0.00 50.09 11.91 95.84 93.45 28 1.486 3 1.485 2.971

    jinfo(Configuration Info for Java):java配置信息工具

    选项作用
    -sysprops获取环境变量

    1. [admin@t-points ~]$ jinfo -sysprops 1351
    2. Attaching to process ID 1351, please wait...
    3. Debugger attached successfully.
    4. Server compiler detected.
    5. JVM version is 25.251-b08
    6. java.runtime.name = Java(TM) SE Runtime Environment
    7. java.vm.version = 25.251-b08
    8. sun.boot.library.path = /usr/java/jdk1.8.0_251-amd64/jre/lib/amd64
    9. java.protocol.handler.pkgs = org.springframework.boot.loader
    10. java.vendor.url = http://java.oracle.com/
    11. java.vm.vendor = Oracle Corporation
    12. path.separator = :
    13. file.encoding.pkg = sun.io
    14. java.vm.name = Java HotSpot(TM) 64-Bit Server VM
    15. sun.os.patch.level = unknown
    16. sun.java.launcher = SUN_STANDARD
    17. user.country = US
    18. user.dir = /
    19. java.vm.specification.name = Java Virtual Machine Specification
    20. PID = 1351
    21. java.runtime.version = 1.8.0_251-b08
    22. java.awt.graphicsenv = sun.awt.X11GraphicsEnvironment
    23. os.arch = amd64
    24. java.endorsed.dirs = /usr/java/jdk1.8.0_251-amd64/jre/lib/endorsed
    25. line.separator =
    26. java.io.tmpdir = /tmp
    27. java.vm.specification.vendor = Oracle Corporation
    28. os.name = Linux
    29. sun.jnu.encoding = UTF-8
    30. jetty.git.hash = 27208684755d94a92186989f695db2d7b21ebc51
    31. java.library.path = /usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib
    32. spring.beaninfo.ignore = true
    33. java.specification.name = Java Platform API Specification
    34. java.class.version = 52.0
    35. sun.management.compiler = HotSpot 64-Bit Tiered Compilers
    36. os.version = 3.10.0-1062.18.1.el7.x86_64
    37. user.home = /home/admin
    38. user.timezone = Asia/Shanghai
    39. catalina.useNaming = false
    40. java.awt.printerjob = sun.print.PSPrinterJob
    41. file.encoding = UTF-8
    42. @appId = integral_mobile
    43. java.specification.version = 1.8
    44. catalina.home = /tmp/tomcat.7673651076886970121.8118
    45. user.name = admin
    46. java.class.path = /home/admin/apps/integral_mobile-0.0.1-SNAPSHOT.jar
    47. java.vm.specification.version = 1.8
    48. sun.arch.data.model = 64
    49. sun.java.command = /home/admin/apps/integral_mobile-0.0.1-SNAPSHOT.jar
    50. java.home = /usr/java/jdk1.8.0_251-amd64/jre
    51. user.language = en
    52. java.specification.vendor = Oracle Corporation
    53. awt.toolkit = sun.awt.X11.XToolkit
    54. java.vm.info = mixed mode
    55. java.version = 1.8.0_251
    56. java.ext.dirs = /usr/java/jdk1.8.0_251-amd64/jre/lib/ext:/usr/java/packages/lib/ext
    57. sun.boot.class.path = /usr/java/jdk1.8.0_251-amd64/jre/lib/resources.jar:/usr/java/jdk1.8.0_251-amd64/jre/lib/rt.jar:/usr/java/jdk1.8.0_251-amd64/jre/lib/sunrsasign.jar:/usr/java/jdk1.8.0_251-amd64/jre/lib/jsse.jar:/usr/java/jdk1.8.0_251-amd64/jre/lib/jce.jar:/usr/java/jdk1.8.0_251-amd64/jre/lib/charsets.jar:/usr/java/jdk1.8.0_251-amd64/jre/lib/jfr.jar:/usr/java/jdk1.8.0_251-amd64/jre/classes
    58. java.awt.headless = true
    59. java.vendor = Oracle Corporation
    60. catalina.base = /tmp/tomcat.7673651076886970121.8118
    61. file.separator = /
    62. java.vendor.url.bug = http://bugreport.sun.com/bugreport/
    63. sun.io.unicode.encoding = UnicodeLittle
    64. sun.cpu.endian = little
    65. sun.cpu.isalist =

    jmap(Memory Map for Java):java内存影响工具

    选项

    作用

    -dump生成Java堆转储快照
    -heap  显示Java堆详细信息、使用哪种回收器、参数配置等
    -histo显示堆中对象统计信息、包括类、对象数量、合计容量
    -F强制生成dump快照
    1. [admin@t-points ~]$ jmap -histo 1351 |head -20
    2. num #instances #bytes class name
    3. ----------------------------------------------
    4. 1: 333202 34434976 [C
    5. 2: 49888 29245832 [B
    6. 3: 19893 13926960 [I
    7. 4: 244165 5859960 java.lang.String
    8. 5: 48470 4265360 java.lang.reflect.Method
    9. 6: 41238 4143776 [Ljava.lang.Object;
    10. 7: 73412 2936480 java.util.HashMap$KeyIterator
    11. 8: 73948 2366336 java.util.concurrent.ConcurrentHashMap$Node
    12. 9: 52068 2082720 java.util.LinkedHashMap$Entry
    13. 10: 14602 1618768 java.lang.Class
    14. 11: 20869 1591656 [Ljava.util.HashMap$Node;
    15. 12: 24694 1382864 java.util.LinkedHashMap
    16. 13: 19429 1243456 java.net.URL
    17. 14: 24069 1155312 org.springframework.util.ConcurrentReferenceHashMap$SoftEntryReference
    18. 15: 30388 972416 java.util.HashMap$Node
    19. 16: 41523 940672 [Ljava.lang.Class;
    20. 17: 11083 886640 org.springframework.boot.loader.jar.JarURLConnection
    21. [admin@t-points ~]$ jmap -heap 1351
    22. Attaching to process ID 1351, please wait...
    23. Debugger attached successfully.
    24. Server compiler detected.
    25. JVM version is 25.251-b08
    26. using thread-local object allocation.
    27. Parallel GC with 2 thread(s)
    28. Heap Configuration:
    29. MinHeapFreeRatio = 0
    30. MaxHeapFreeRatio = 100
    31. MaxHeapSize = 536870912 (512.0MB)
    32. NewSize = 178782208 (170.5MB)
    33. MaxNewSize = 178782208 (170.5MB)
    34. OldSize = 358088704 (341.5MB)
    35. NewRatio = 2
    36. SurvivorRatio = 8
    37. MetaspaceSize = 21807104 (20.796875MB)
    38. CompressedClassSpaceSize = 1073741824 (1024.0MB)
    39. MaxMetaspaceSize = 17592186044415 MB
    40. G1HeapRegionSize = 0 (0.0MB)
    41. Heap Usage:
    42. PS Young Generation
    43. Eden Space:
    44. capacity = 160956416 (153.5MB)
    45. used = 85097896 (81.15567779541016MB)
    46. free = 75858520 (72.34432220458984MB)
    47. 52.870148400918666% used
    48. From Space:
    49. capacity = 7340032 (7.0MB)
    50. used = 6389792 (6.093780517578125MB)
    51. free = 950240 (0.906219482421875MB)
    52. 87.05400739397321% used
    53. To Space:
    54. capacity = 8912896 (8.5MB)
    55. used = 0 (0.0MB)
    56. free = 8912896 (8.5MB)
    57. 0.0% used
    58. PS Old Generation
    59. capacity = 358088704 (341.5MB)
    60. used = 42655824 (40.67976379394531MB)
    61. free = 315432880 (300.8202362060547MB)
    62. 11.91208310218018% used

    jstack(java堆栈跟踪工具)

    选项        作用
    -F       当正常输出的请求不响应是,强制输出线程堆栈
    -l处堆栈外,显示关于锁的附加信息
    1. [admin@t-points ~]$ jstack -l 1351
    2. 2022-08-08 20:05:48
    3. Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.251-b08 mixed mode):
    4. "Attach Listener" #108 daemon prio=9 os_prio=0 tid=0x00007f7b40001800 nid=0x1c3f waiting on condition [0x0000000000000000]
    5. java.lang.Thread.State: RUNNABLE
    6. Locked ownable synchronizers:
    7. - None
    8. "qtp1002276800-107" #107 prio=5 os_prio=0 tid=0x00007f7b3c47a800 nid=0x1951 waiting on condition [0x00007f7b1dbe2000]
    9. java.lang.Thread.State: TIMED_WAITING (parking)
    10. at sun.misc.Unsafe.park(Native Method)
    11. - parking to wait for <0x00000000e269ded8> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
    12. at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215)
    13. at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2078)
    14. at org.eclipse.jetty.util.BlockingArrayQueue.poll(BlockingArrayQueue.java:392)
    15. at org.eclipse.jetty.util.thread.QueuedThreadPool.idleJobPoll(QueuedThreadPool.java:656)
    16. at org.eclipse.jetty.util.thread.QueuedThreadPool.access$800(QueuedThreadPool.java:49)
    17. at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:720)
    18. at java.lang.Thread.run(Thread.java:748)
    19. Locked ownable synchronizers:
    20. - None

    2.可视化工具

    JConsole:java监视与管理控制台

    JConsole是一款基于JMX的可视化监视、管理工具。

    JConsole在javahome/bin目录下,jconsole.exe

    在这里插入图片描述

    在这里插入图片描述

    等等

    VisualVM是功能强大的运行监视和故障处理软件之一。可以安装很多插件,集成很多功能。

    VisualVM,能够监控线程,内存情况,查看方法的CPU时间和内存中的对 象,已被GC的对象,反向查看分配的堆栈(如100个String对象分别由哪几个对象分配出来的)。

    在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述

     arthas:是 Alibaba 开源的 Java 诊断工具,非常好用

     Arthas 是一款线上监控诊断产品,通过全局视角实时查看应用 load、内存、gc、线程的状态信息,并能在不修改应用代码的情况下,对业务问题进行诊断,包括查看方法调用的出入参、异常,监测方法执行耗时,类加载信息等,大大提升线上问题排查效率。

     安装使用:官网地址:简介 | arthas

    1. curl -O https://arthas.aliyun.com/arthas-boot.jar
    2. java -jar arthas-boot.jar

     启动

    1. [INFO] Try to attach process 71560
    2. [INFO] Attach process 71560 success.
    3. [INFO] arthas-client connect 127.0.0.1 3658
    4. ,---. ,------. ,--------.,--. ,--. ,---. ,---.
    5. / O \ | .--. ''--. .--'| '--' | / O \ ' .-'
    6. | .-. || '--'.' | | | .--. || .-. |`. `-.
    7. | | | || |\ \ | | | | | || | | |.-' |
    8. `--' `--'`--' '--' `--' `--' `--'`--' `--'`-----'
    9. wiki: https://arthas.aliyun.com/doc
    10. version: 3.0.5.20181127201536
    11. pid: 71560
    12. time: 2018-11-28 19:16:24

    查看dashboard

    1. $ dashboard
    2. ID NAME GROUP PRIORI STATE %CPU TIME INTERRU DAEMON
    3. 17 pool-2-thread-1 system 5 WAITIN 67 0:0 false false
    4. 27 Timer-for-arthas-dashb system 10 RUNNAB 32 0:0 false true
    5. 11 AsyncAppender-Worker-a system 9 WAITIN 0 0:0 false true
    6. 9 Attach Listener system 9 RUNNAB 0 0:0 false true
    7. 3 Finalizer system 8 WAITIN 0 0:0 false true
    8. 2 Reference Handler system 10 WAITIN 0 0:0 false true
    9. 4 Signal Dispatcher system 9 RUNNAB 0 0:0 false true
    10. 26 as-command-execute-dae system 10 TIMED_ 0 0:0 false true
    11. 13 job-timeout system 9 TIMED_ 0 0:0 false true
    12. 1 main main 5 TIMED_ 0 0:0 false false
    13. 14 nioEventLoopGroup-2-1 system 10 RUNNAB 0 0:0 false false
    14. 18 nioEventLoopGroup-2-2 system 10 RUNNAB 0 0:0 false false
    15. 23 nioEventLoopGroup-2-3 system 10 RUNNAB 0 0:0 false false
    16. 15 nioEventLoopGroup-3-1 system 10 RUNNAB 0 0:0 false false
    17. Memory used total max usage GC
    18. heap 32M 155M 1820M 1.77% gc.ps_scavenge.count 4
    19. ps_eden_space 14M 65M 672M 2.21% gc.ps_scavenge.time(m 166
    20. ps_survivor_space 4M 5M 5M s)
    21. ps_old_gen 12M 85M 1365M 0.91% gc.ps_marksweep.count 0
    22. nonheap 20M 23M -1 gc.ps_marksweep.time( 0
    23. code_cache 3M 5M 240M 1.32% ms)
    24. Runtime
    25. os.name Mac OS X
    26. os.version 10.13.4
    27. java.version 1.8.0_162
    28. java.home /Library/Java/JavaVir
    29. tualMachines/jdk1.8.0
    30. _162.jdk/Contents/Hom
    31. e/jre

    三、JVM调优策略

    1.选择合适的垃圾回收器

    • CPU单核,那么毫无疑问Serial 垃圾收集器是你唯一的选择。
    • CPU多核,关注吞吐量 ,那么选择PS+PO组合。
    • CPU多核,关注用户停顿时间,JDK版本1.6或者1.7,那么选择CMS。
    • CPU多核,关注用户停顿时间,JDK1.8及以上,JVM可用内存6G以上,那么选择G1。
    1. //设置Serial垃圾收集器(新生代)
    2. 开启:-XX:+UseSerialGC
    3. //设置PS+PO,新生代使用功能Parallel Scavenge 老年代将会使用Parallel Old收集器
    4. 开启 -XX:+UseParallelOldGC
    5. //CMS垃圾收集器(老年代)
    6. 开启 -XX:+UseConcMarkSweepGC
    7. //设置G1垃圾收集器
    8. 开启 -XX:+UseG1GC

    2.调整内存大小

    现象:垃圾收集频率非常频繁。

    原因:如果内存太小,就会导致频繁的需要进行垃圾收集才能释放出足够的空间来创建新的对象,所以增加堆内存大小的效果是非常显而易见的。

    注意:如果垃圾收集次数非常频繁,但是每次能回收的对象非常少,那么这个时候并非内存太小,而可能是内存泄露导致对象无法回收,从而造成频繁GC。

    参数配置:

    1. //设置堆初始值
    2. 指令1:-Xms2g
    3. 指令2:-XX:InitialHeapSize=2048m
    4. //设置堆区最大值
    5. 指令1`-Xmx2g`
    6. 指令2: -XX:MaxHeapSize=2048m
    7. //新生代内存配置
    8. 指令1:-Xmn512m
    9. 指令2:-XX:MaxNewSize=512m

    3.调整大对象的标准

    现象:老年代频繁GC,每次回收的对象很多,而且单个对象的体积都比较大。

    原因:如果大量的大对象直接分配到老年代,导致老年代容易被填满而造成频繁GC,可设置对象直接进入老年代的标准。

    注意:这些大对象进入新生代后可能会使新生代的GC频率和时间增加。

    配置参数:

    1. //新生代可容纳的最大对象,大于则直接会分配到老年代,0代表没有限制。
    2. -XX:PretenureSizeThreshold=1000000

    4.调整GC的触发时机

    现象:CMS,G1 经常 Full GC,程序卡顿严重。

    原因:G1和CMS 部分GC阶段是并发进行的,业务线程和垃圾收集线程一起工作,也就说明垃圾收集的过程中业务线程会生成新的对象,所以在GC的时候需要预留一部分内存空间来容纳新产生的对象,如果这个时候内存空间不足以容纳新产生的对象,那么JVM就会停止并发收集暂停所有业务线程(STW)来保证垃圾收集的正常运行。这个时候可以调整GC触发的时机(比如在老年代占用60%就触发GC),这样就可以预留足够的空间来让业务线程创建的对象有足够的空间分配。

    注意:提早触发GC会增加老年代GC的频率。

    配置参数:

    1. //使用多少比例的老年代后开始CMS收集,默认是68%,如果频繁发生SerialOld卡顿,应该调小
    2. -XX:CMSInitiatingOccupancyFraction
    3. //G1混合垃圾回收周期中要包括的旧区域设置占用率阈值。默认占用率为 65%
    4. -XX:G1MixedGCLiveThresholdPercent=65

    5.更多调优策略

    【JVM系列5】JVM调优实例 - 知乎

    JVM实战调优 - zydbky - 博客园

    JVM参数调优总结 -Xms -Xmx -Xmn -Xss_jakeswang的博客-CSDN博客_jvm xms xmx 参数详解

    看书:深入理解Java虚拟机

    如果本篇博客对您有一定的帮助,大家记得留言+点赞+收藏

  • 相关阅读:
    reg[0:3] 与reg[3:0] 流水灯
    僵尸进程的产生原因和解决方法
    LoRaWan模块应用于智慧城市景观灯
    redis的集群
    电脑便签功能在哪里找?电脑桌面便签怎么添加?
    C++中的运算符重载
    Java数字处理类--Math类--大数字运算
    2022第十一届PMO大会(线上会议)成功召开
    网络爬虫中selenium和requests这两个工具有什么区别呢?
    图论——强连通分量缩点+拓扑排序
  • 原文地址:https://blog.csdn.net/promsing/article/details/126232985