JVM 性能调优

2023-12-13 13:22:38

JVM 性能调优

JVM(Java Virtual Machine)性能调优是优化Java应用程序性能的关键步骤。以下是一些应该考虑的JVM性能调优方面:

一、 堆内存调整:

1、调整堆内存大小,包括新生代和老年代的大小。

? 了解程序的运行状况,查看其活跃的数据量。活跃的数据量包括应用程序运行于稳定状态时,老年代占用的java堆大小和永久代占用的java堆大小。

? 根据活跃的数据量配置堆以及其他参数。老年代空间大小不应该小于活跃数据大小的1.5倍。新生代空间至少应为Java堆的10%. 新生代空间应该为老年代空间活跃数据的1~1.5倍。

? 增大 Java 堆大小时,需要注意不要超过JVM可用的物理内存数。

? 日志分析可以帮助您更好地了解程序的运行状况。您可以通过日志分析来查看程序的运行频率、耗时等信息。

2、 使用JVM参数 -Xms-Xmx 来设置初始堆大小和最大堆大小,以适应应用程序的内存需求。

二、 垃圾收集器选择:

1、选择合适的垃圾收集器,根据应用程序的性质和需求。

2、 一些常见的垃圾收集器包括Serial、Parallel、CMS(Concurrent Mark-Sweep)、G1(Garbage-First)等。

不同的垃圾收集器在吞吐量、响应时间和内存占用等方面有不同的特点。以下是Serial、Parallel、CMS(Concurrent Mark-Sweep)、G1(Garbage-First)垃圾收集器的优劣点和一般的使用策略:

  1. **Serial 收集器:**
     - **优点:**
       - 单线程执行,简单高效。
       - 对于小型应用和单核处理器的环境,性能较好。
     - **缺点:**
       - 不适用于多核处理器,不能充分利用硬件资源。
       - 在垃圾收集期间,应用程序暂停。
     - **适用场景:**
       - 移动设备、小型应用、开发和测试环境。

  2. **Parallel 收集器:**
     - **优点:**
       - 多线程执行,适用于多核处理器,提供更高的吞吐量。
       - 在垃圾收集期间,应用程序暂停时间相对较短。
     - **缺点:**
       - 仍然有较长的暂停时间,不适合对延迟敏感的应用。
     - **适用场景:**
       - 吞吐量优先的应用,例如后台计算和数据处理。

  3. **CMS(Concurrent Mark-Sweep)收集器:**
     - **优点:**
       - 通过并发标记和清除,减少了垃圾收集暂停时间,适合对延迟敏感的应用。
       - 在老年代的垃圾收集中表现较好。
     - **缺点:**
       - 由于并发执行,可能导致更多的碎片,影响长时间运行的性能。
       - CMS收集器在处理幸存对象时可能需要重新扫描老年代。
     - **适用场景:**
       - 对延迟敏感的应用,老年代的垃圾收集较为频繁。

  4. **G1(Garbage-First)收集器:**
     - **优点:**
       - 通过划分整个堆空间为多个小块,实现更精细的垃圾收集。
       - 在大堆和多核环境中提供更稳定的性能。
       - 具有可预测的停顿时间,适用于对延迟敏感的应用。
     - **缺点:**
       - 在某些情况下,吞吐量可能低于Parallel收集器。
       - 相对较复杂的算法,可能引入一些额外的开销。
     - **适用场景:**
       - 大堆、对延迟敏感的应用,以及需要稳定性能的场景。

通常的使用策略:

  • 对于小型应用或开发测试环境,可以选择使用Serial收集器。
  • 对于吞吐量优先的应用,例如后台计算和数据处理,可以选择Parallel收集器。
  • 对于对延迟敏感的应用,可以选择CMS或G1收集器,取决于应用的具体特点和需求。
  • 在Java 9及之后的版本,G1收集器成为默认的垃圾收集器,可以考虑直接使用G1,并根据实际性能进行调优。

总体而言,选择垃圾收集器应该根据应用的性质、硬件环境、性能需求和内存特征等因素进行综合考虑。性能测试和监测是选择最合适收集器的关键。

三、 新生代比例和参数:

1、 设置新生代的比例,可以使用参数 -XX:NewRatio

2、通过调整 -XX:SurvivorRatio 参数来平衡Eden区和Survivor区的大小。

四、 并行度和线程数量:

1、调整垃圾收集器的并行度,可以使用参数如 -XX:ParallelGCThreads

2、选择合适的线程数量以平衡吞吐量和响应时间。

五. 永久代(Java 8之前)和元空间(Java 8及之后):

1、Java 8及之后使用元空间替代了永久代,可以通过参数 -XX:MaxMetaspaceSize 来设置元空间的最大大小。

2、对于Java 8及之前的版本,可以通过参数 -XX:MaxPermSize 来设置永久代的最大大小。

六、 栈和堆栈大小:

1、根据应用程序的调用深度和并发度,调整栈的大小。

2、使用参数 -Xss 来设置线程的堆栈大小。

七、 类加载优化:

1、使用参数 -XX:+TraceClassLoading-XX:+TraceClassUnloading 来跟踪类加载和卸载。

2、通过使用参数 -XX:+CMSClassUnloadingEnabled 来允许CMS收集器卸载不再使用的类。

八、 即时编译器(JIT)优化:

1、使用 -XX:+PrintCompilation 参数来观察JIT编译的过程。

2、考虑调整 -XX:CompileThreshold 参数,以更好地适应应用程序的性能特征。

九、内存分析工具:

1、使用内存分析工具(如VisualVM、JConsole、YourKit等)来监控堆内存使用情况、垃圾收集行为等。

VisualVM 是 jdk 自带的,可以直接打开,并且还是中文版本的,注意 M1 的 mac 是没有的!!!

工具的对比分析如下:

以下是一些常见的内存分析工具:

  1. VisualVM: 一个功能齐全的Java虚拟机监控和分析工具。它包含了一系列插件和功能,可以监视应用程序的内存使用、线程状况、垃圾收集等。VisualVM还提供了堆转储和线程转储功能,方便您进行更详细的分析。
  2. YourKit Java Profiler: 一款商业级的Java性能分析工具,具有强大的内存分析功能
  3. Linux常见的内存分析工具:vmstat、iostat、dstat、iotop、pidstat、top、htop、mpstat、netstat、ps、strace等

2、分析内存泄漏和大对象的情况,以便及时采取措施。

十、 GC日志和分析:

1、启用垃圾收集日志,使用参数 -Xloggc:<filename>

-XX:+PrintGCDetails

2、使用工具(如GCViewer、GCEasy等)来分析垃圾收集日志,以了解GC行为和性能瓶颈。

十一、 性能测试和基准测试:

1、进行全面的性能测试和基准测试,以评估吞吐量、响应时间和资源利用率等性能指标。

测试工具有 LoadRunnerJMeterGatling 等,日常使用一般都是 JMeter,可以同时进行压测,文档接口可以使用 APIFox 或者 Yapi,后者是开源的,同时可以做一些环境测试和接口测试,但是注意官方版不支持三级目录。

2、根据测试结果调整JVM参数和应用程序代码。

十二、 代码优化:

1、优化应用程序代码,减少不必要的内存分配、降低锁竞争、避免频繁的IO操作等。

2、使用工具(如JProfiler、YourKit等)来进行代码级别的性能分析。

这些方面提供了一些常见的JVM性能调优的考虑点。在进行性能调优时,建议通过监测、测试和分析来全面评估系统的性能,并根据实际需求进行有针对性的调整。

文章来源:https://blog.csdn.net/weiyi_1/article/details/134538340
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。