JVM实战调优之调优IDEA

最近在阅读《深入理解Java虚拟机》这本书,看到了其中的Eclipse运行速度调优,属实手痒难耐,决定对IDEA操作一番。一方面作为练习,一方面巩固知识。
本文章仅作记录jvm的练习和idea的使用技巧。欢迎各位指教和交流。

JVM调优

准备工作

运行环境

  • 64位Windows 10系统、16G内存。
  • IDEA 2022.3.2,不同版本的IDEA使用的内置JVM不同。
  • Java visualVM 2.1.5. + visual gc插件
  • notepad++,用来打开idea.vmoptions

在这里插入图片描述

初始配置:idea.vmoptions,上图中可以看到路径。接下来的操作需要修改这个文件,记得备份。

-Xms128m
-Xmx1024m
-XX:ReservedCodeCacheSize=512m
-XX:+IgnoreUnrecognizedVMOptions
-XX:+UseG1GC
-XX:SoftRefLRUPolicyMSPerMB=50
-XX:CICompilerCount=2
-XX:+HeapDumpOnOutOfMemoryError
-XX:-OmitStackTraceInFastThrow
-ea
-Dsun.io.useCanonCaches=false
-Djdk.http.auth.tunneling.disabledSchemes=""
-Djdk.attach.allowAttachSelf=true
-Djdk.module.illegalAccess.silent=true
-Dkotlinx.coroutines.debug=off
-XX:ErrorFile=$USER_HOME/java_error_in_idea_%p.log
-XX:HeapDumpPath=$USER_HOME/java_error_in_idea.hprof

--add-opens=java.base/jdk.internal.org.objectweb.asm=ALL-UNNAMED
--add-opens=java.base/jdk.internal.org.objectweb.asm.tree=ALL-UNNAMED

启动时间显示插件。
在这里插入图片描述

分析

开启GC日志
idea.vmoptions中添加

-verbose:gc 
-XX: +PrintCommandLineFlags
-Xloggc:C:\Users\xxx\Desktop\idea_gc.log
  • -verbose:gc:在控制台输出GC情况
  • -XX: +PrintCommandLineFlags:程序运行时,打印虚拟机接受到的命令行显式参数
  • -Xloggc:[指定文件位置]:打印文件到指定路径

打开idea

在这里插入图片描述

在这里插入图片描述

此时我们可以获得以下信息。

  • 没有进行堆的扩容。
  • 进行了52次GC。52次都是新生代的GC,没有比较耗时的老年代GC。
  • 开启时长3s左右
  • 使用了GC收集器
  • IDEA2022.3.2确实强大

实战

我们的调优思路可以从几个方面进行

  • 更换Java版本,选择合适的垃圾收集器
  • 避免堆的频繁扩容,调整堆的大小,减少GC的次数
  • 调整元空间的大小
  • 类加载时间优化
  • 视情况调整老年代的占比

1、更换Java版本,选择合适的垃圾收集器
在 JDK 8 中,Parallel是默认设置,但在 JDK 9 中改为了 G1。从那以后,G1 的改进速度就超过了 Parallel,但在有些情况下可能 Parallel 仍然是最佳选择。ZGC(从 JDK 15 开始正式使用)的加入,成为了第三种高性能替代方案。
IDEA2022.3.2版本内置的JDK17默认使用GC垃圾收集器,这里我们可以测试ZGC垃圾收集器。
将配置文件中的-XX:+UseG1GC换成-XX:+UseZGC。笔者的分析工具从1.8升级到2.1.5(目前官网最新版),都无法查看ZGC的Visual GC。所以我们分析以下日志。

  • gc次数明显减少。但并不知道耗时是否低于G1。后续的使用中发现有卡顿的现象,慎用。
    在这里插入图片描述
[0.024s][info][gc] Using The Z Garbage Collector
[1.202s][info][gc] GC(0) Garbage Collection (Metadata GC Threshold) 88M(9%)->106M(10%)
[1.562s][info][gc] GC(1) Garbage Collection (Warmup) 112M(11%)->86M(8%)
[2.712s][info][gc] GC(2) Garbage Collection (Warmup) 216M(21%)->226M(22%)
[3.799s][info][gc] GC(3) Garbage Collection (Warmup) 332M(32%)->194M(19%)
[9.127s][info][gc] Allocation Stall (AWT-EventQueue-0) 137.776ms
[9.127s][info][gc] Allocation Stall (DefaultDispatcher-worker-7) 69.313ms
[9.127s][info][gc] Allocation Stall (DefaultDispatcher-worker-59) 19.475ms
[9.127s][info][gc] Allocation Stall (DefaultDispatcher-worker-29) 222.981ms
[9.127s][info][gc] Allocation Stall (DefaultDispatcher-worker-9) 8.958ms
[9.173s][info][gc] Allocation Stall (DefaultDispatcher-worker-29) 6.145ms
[9.173s][info][gc] Allocation Stall (AWT-EventQueue-0) 32.246ms
[9.173s][info][gc] Allocation Stall (DefaultDispatcher-worker-59) 2.432ms
[9.224s][info][gc] Relocation Stall (DefaultDispatcher-worker-7) 58.346ms
[9.279s][info][gc] GC(4) Garbage Collection (Metadata GC Threshold) 870M(85%)->454M(44%)
[9.936s][info][gc] GC(5) Garbage Collection (Allocation Stall) 460M(45%)->316M(31%)
[10.862s][info][gc] GC(6) Garbage Collection (Allocation Rate) 366M(36%)->240M(23%)
[16.528s][info][gc] GC(7) Garbage Collection (Allocation Rate) 746M(73%)->384M(38%)
[21.600s][info][gc] GC(8) Garbage Collection (Allocation Rate) 822M(80%)->428M(42%)
[22.702s][info][gc] GC(9) Garbage Collection (Allocation Rate) 518M(51%)->354M(35%)
[24.586s][info][gc] GC(10) Garbage Collection (Allocation Rate) 410M(40%)->420M(41%)
[25.551s][info][gc] GC(11) Garbage Collection (Allocation Rate) 452M(44%)->344M(34%)
[27.288s][info][gc] GC(12) Garbage Collection (Allocation Rate) 530M(52%)->376M(37%)
[29.007s][info][gc] GC(13) Garbage Collection (Allocation Rate) 606M(59%)->448M(44%)
[29.607s][info][gc] GC(14) Garbage Collection (Allocation Rate) 470M(46%)->458M(45%)
[30.541s][info][gc] GC(15) Garbage Collection (Allocation Rate) 618M(60%)->422M(41%)
[31.800s][info][gc] GC(16) Garbage Collection (Allocation Rate) 668M(65%)->426M(42%)
[32.724s][info][gc] GC(17) Garbage Collection (Allocation Rate) 634M(62%)->482M(47%)
[33.906s][info][gc] GC(18) Garbage Collection (Allocation Rate) 670M(65%)->434M(42%)
[36.047s][info][gc] GC(19) Garbage Collection (Allocation Rate) 784M(77%)->386M(38%)
[39.570s][info][gc] GC(20) Garbage Collection (Allocation Rate) 838M(82%)->418M(41%)
[41.805s][info][gc] GC(21) Garbage Collection (Allocation Rate) 630M(62%)->356M(35%)
[76.509s][info][gc] GC(22) Garbage Collection (Proactive) 540M(53%)->358M(35%)
[110.519s][info][gc] GC(23) Garbage Collection (Proactive) 528M(52%)->334M(33%)
[143.496s][info][gc] GC(24) Garbage Collection (Proactive) 494M(48%)->334M(33%)

2、避免堆的频繁扩容,调整堆的大小,减少GC的次数
我们可以通过固定堆的大小,减少GC,避免频繁扩容。可以看到,比起最开始,Eden的GC次数下降了一半,时间减少了100ms。然而,我们发现,元空间几乎是满的,日志里也有几次元空间的GC。

-Xms2028m 初始堆内存
-Xmx2028m 最大堆内存

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3. 调整元空间的大小
-XX:MetaspaceSize=512m 设置元空间初始大小。看得出,刚才元空间的四次GC消失了,分配大小没有变化,GC时间只减少一点点,也可能没有变化。所以这一步可以忽略。
在这里插入图片描述

4. 类加载时间优化
根据之前的日志,可以看出,CLass Loader的时间基本上在40~50s。这里我们默认Idea的代码安全。通过-Xverify:none关闭验证字节码的验证。
在这里插入图片描述
经过测试,CLass Loader基本在40s左右了。

总结

一番调试,发现今天翻车了。上次的成功调试,是因为我当时用的是idea2021,它内置的java版本远不及现在的17。最新版本的idea,除了将堆调大点外,其他的优化已经不是初学者(我)能进行的。技术在迭代,性能也在不断的上升,可以说,互联网的领军者已经在不断突破硬件利用率的瓶颈,而紧跟其后的就是软件的更新。希望诸君通过自己的努力,能在诺大的互联网,拥有一席之地。

IDEA使用调整

热加载

在过去很长一段时间中,笔者陷入了只修改一处代码,却需要重启整个项目的困扰。偶然发现了IDEA的一个强大功能:修改一处,只编译一处。

注意:1、笔者之前开启热部署的时候,已经修改了一些配置,对接下的情况应该会有影响,但是在本次实验的项目并没有引入热部署依赖,所以读者可以自行查看一下热部署需要开启的配置,决定是否开启。2、需在Debug模式下,新增方法、变量,修改配置文件,模板引擎页面默认开启缓存的问题,这时候只能重启。

我们在Debug模式下,在接口中加了一行代码。
在这里插入图片描述

三种编译方式:整个项目,单个模块,单个文件。
选择编译方式:单个文件。如果是灰色,可以随便修改点东西再撤销。
在这里插入图片描述

可以看到编译完成
在这里插入图片描述
测试
在这里插入图片描述

忽略不需要启动的项目

  • 我们可以忽略不需要编译的项目,提高maven的编译速度。
    实际开发中,并不是每一个项目都需要去使用,我们可以排除那些无需编译的项目

    视情况移出,建议点否,移除会导致其他地方的引用需要重新Reload
    在这里插入图片描述
    当然,如果修改了被忽略的模块,需要手动编译一下。

减少索引时间

开启项目的时候需要加载文件索引,这是个相当耗时的操作。我们可以通过排除压根用不上的模块来提升体验。
在这里插入图片描述

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
JVM参数是为了提高Java应用程序的性能和稳定性。下面是一些常见的JVM参数的思路和建议: 1. 堆内存设置: - -Xms: 初始堆大小,建议与-Xmx相同,避免堆大小的动态整。 - -Xmx: 最大堆大小,根据应用程序的需求进行设置,避免频繁的垃圾回收。 2. 垃圾回收器选择: - -XX:+UseParallelGC: 使用并行垃圾回收器,适合多核CPU和高吞吐量应用。 - -XX:+UseConcMarkSweepGC: 使用CMS垃圾回收器,适合响应时间先的应用。 - -XX:+UseG1GC: 使用G1垃圾回收器,适合大内存应用和低延迟要求。 3. 垃圾回收参数: - -XX:NewRatio: 设置新生代和老年代的比例,默认为2,可以根据应用程序的对象生命周期进行整。 - -XX:SurvivorRatio: 设置Eden区和Survivor区的比例,默认为8,可以根据对象的存活率进行整。 - -XX:MaxTenuringThreshold: 设置对象进入老年代的年龄阈值,默认为15,可以根据对象的存活率和内存情况进行整。 4. 线程相关参数: - -Xss: 设置线程栈的大小,默认为1M,可以根据应用程序的线程数量进行整。 - -XX:ParallelGCThreads: 并行垃圾回收的线程数量,默认为CPU核心数的1/8,可以根据CPU和内存情况进行整。 5. 其他常用参数: - -XX:+UseCompressedOops: 使用压缩指针,可以减少对象引用的内存消耗。 - -XX:+DisableExplicitGC: 禁用显示用System.gc()方法,避免不必要的垃圾回收。 以上是一些常见的JVM参数策略,具体的效果和最佳参数设置还需要根据应用程序的实际情况进行测试和整。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值