JVM-JVM性能调优

JVM性能调优的目标和方法

JVM性能调优的目标是使JVM在运行Java应用程序时能够更加高效地利用计算机的资源,以提高应用程序的性能和响应能力。具体来说,JVM性能调优的目标可以包括以下几个方面:

  1. 提高应用程序的吞吐量:通过优化JVM的内存管理、垃圾回收和线程管理等方面,减少JVM的开销,提高应用程序的吞吐量。
  2. 减少应用程序的延迟:通过优化JVM的垃圾回收策略、调整线程池大小等方面,减少应用程序的延迟,提高用户体验。
  3. 减少JVM的内存占用:通过优化JVM的内存管理策略,减少JVM的内存占用,提高系统的稳定性。

JVM性能调优的方法可以包括以下几个方面:

  1. 调整JVM的内存参数:通过调整JVM的内存参数(如-Xms、-Xmx、-Xmn等),控制JVM的堆内存和非堆内存的大小,避免内存泄漏和OOM(Out Of Memory)等问题。
  2. 选择合适的垃圾回收器:JVM提供了多种垃圾回收器(如Serial、Parallel、CMS、G1等),根据应用程序的特点选择合适的垃圾回收器,并调整其参数,以达到最佳的垃圾回收效果。
  3. 调整线程池大小:通过调整线程池大小,避免线程过多或过少的情况,从而提高应用程序的并发处理能力。
  4. 使用性能分析工具:使用性能分析工具(如JProfiler、VisualVM、Arthas工具;jstst jstack jmap命令等)对应用程序进行分析,找出瓶颈和性能问题,并进行优化。
  5. 优化代码:优化代码(如避免频繁创建对象、避免过多的方法调用等),减少JVM的开销,提高应用程序的性能。

JVM性能调优的指标和工具

JVM性能调优的指标是衡量JVM性能的重要标准,常见的指标包括以下几个方面:

  1. 堆内存使用率:表示JVM堆内存的使用情况,通常应该控制在70%以下,避免出现OOM等内存问题。
  2. 垃圾回收时间:表示JVM进行垃圾回收所消耗的时间,过长的垃圾回收时间会影响应用程序的性能。
  3. 线程数:表示JVM当前运行的线程数,过多或过少的线程数都会影响应用程序的性能。
  4. CPU使用率:表示JVM占用CPU的情况,过高的CPU使用率会影响应用程序的性能。
  5. 响应时间:表示应用程序响应请求的时间,应尽可能缩短响应时间,提高用户体验。

常用的JVM性能调优工具包括以下几个方面:

  1. JVisualVM:是JDK自带的一个性能分析工具,可以用于监控JVM的堆内存、垃圾回收、线程等情况,并可以进行线程分析、内存分析等操作。
  2. JProfiler:是一款商业的性能分析工具,可以提供更为细致的性能分析和优化,支持多种JVM环境和应用程序类型。
  3. GCViewer:是一款开源的垃圾回收日志分析工具,可以用于分析JVM的GC日志,帮助用户理解垃圾回收的情况。
  4. VisualGC:是一款可视化的JVM性能监控工具,可以用于实时监控JVM的内存、垃圾回收等情况。
  5. Perf:是一款Linux系统自带的性能分析工具,可以用于监控系统的CPU、内存、I/O等情况,也可以用于监控JVM的性能。
  6. MAT:MAT是一款Java内存分析器,全称为Eclipse Memory Analyzer Tool。MAT可以帮助开发人员快速分析Java应用程序的内存使用情况,找出内存泄漏和内存浪费等问题,并提供优化建议。

JVM性能调优的技巧和建议

以下是JVM性能调优的一些技巧和建议:

  1. 选择合适的垃圾回收器:根据应用程序的特点选择合适的垃圾回收器,并根据实际情况调整其参数。不同的垃圾回收器适用于不同的应用场景。
  2. 控制堆内存大小:通过调整JVM的堆内存大小,避免内存泄漏和OOM等问题。通常建议将-Xmx参数设置为物理内存的70%左右。
  3. 避免创建过多的对象:尽量避免在循环中频繁创建对象,可以使用对象池等技术优化代码。
  4. 使用线程池:通过使用线程池,可以避免线程过多或过少的情况,提高应用程序的并发处理能力。
  5. 避免过多的方法调用:过多的方法调用会增加JVM的开销,影响应用程序的性能。可以通过内联等技术优化代码。
  6. 避免过度同步:过度同步会降低应用程序的并发处理能力,影响应用程序的性能。可以通过使用锁分离等技术优化代码。
  7. 使用性能分析工具:使用性能分析工具帮助定位性能瓶颈和问题,并进行优化。常用的性能分析工具包括JProfiler、VisualVM、GCViewer等。
  8. 定期进行性能测试:定期进行性能测试,发现性能问题并及时进行优化。可以使用JMeter等工具进行性能测试。
  9. 优化JVM启动参数:通过调整JVM启动参数,可以提高JVM的性能和稳定性。常用的JVM启动参数包括-Xms、-Xmx、-XX:+UseG1GC等。

总之,JVM性能调优是一个复杂的过程,需要根据具体的应用程序进行优化。通过合理选择垃圾回收器、控制堆内存大小、优化代码等技术手段,可以提高JVM的性能和稳定性,提高应用程序的性能和响应能力。

JVM性能调优实战

JVM相关参数

JVM参数分为3类:

  • 标准参数(-),所有JVM都必须支持这些参数的功能,而且向后兼容
  • 非标准参数(-X),默认JVM实现这些参数的功能,但是并不保证所有JVM实现都满足,且不保证向后兼容
  • 非稳定参数(-XX),此类参数各个JVM实现会有所不同,将来可能会不被支持,需要慎重使用

JVM标准参数

  1. -server/-client:指定JVM运行模式,-server表示服务器模式,优化长时间运行的服务器应用程序,-client表示客户端模式,优化启动速度和响应时间。
  2. -classpath/-cp:指定类路径,用于查找类文件和资源文件。
  3. -Dproperty=value:设置系统属性,可以在应用程序中通过System.getProperty()方法获取。
  4. -verbose:class:显示类加载信息,包括类名、加载时间和类加载器等。
  5. -version:显示JVM版本信息。
  6. -showversion:显示JVM版本信息和构建信息。
  7. -help:显示JVM命令行参数帮助信息。

堆栈内存设置参数

  1. -Xms:初始堆大小,默认值为内存的1/64
  2. -Xmx:最大堆大小,默认值为内存1/4
  3. -Xmn:年轻代初始大小,-Xmn参数的默认值为年轻代和老年代的比例为1:2,即年轻代占整个堆的1/3
  4. -XX:NewSize:设置年轻代大小;-Xmn和-XX:NewSize区别:参数的作用范围不同:-Xmn参数只作用于年轻代,而-XX:NewSize参数作用于年轻代和Survivor区;参数的默认值不同:-Xmn参数的默认值是根据堆大小计算得出的,而-XX:NewSize参数的默认值为0,表示JVM会自动计算年轻代和Survivor区的大小
  5. -XX:MaxNewSize:年轻代最大值
  6. -XX:NewRatio:年轻代(包括Eden和两个Survivor区)与年老代的比值(除去持久代)
  7. -XX:SurvivorRatio:Eden区与Survivor区的大小比值,默认值设置为8,则两个Survivor区与一个Eden区的比值为2:8,一个Survivor区占整个年轻代的1/10
  8. -Xss:每个线程的堆栈大小,JDK5.0以后每个线程堆栈大小默认值为1M
  9. -XX:ThreadStackSize:用于设置线程栈的大小 -Xss和-XX:ThreadStackSize区别:参数的作用范围不同:-XX:ThreadStackSize参数用于设置所有线程的栈大小,而-Xss参数用于设置单个线程的栈大小
  10. -XX:LargePageSizeInBytes:用于设置大页面的大小。启用大页面可以提高内存访问的效率,从而提高应用程序的性能和响应能力。但是需要注意的是,启用大页面可能会导致内存碎片的问题,从而影响内存的使用效率和稳定性。
  11. -XX:MaxTenuringThreshold:用于设置对象在年轻代和老年代之间存活的最大年龄。年轻代是Java堆内存中的一部分,用于存放新创建的对象。当年轻代满了之后,会触发一次垃圾回收,将存活的对象移动到老年代中。默认值为15,表示对象最多存活15次垃圾回收之后,就会被移动到老年代中。
  12. -Xnoclassgc:用于控制JVM是否在垃圾回收时回收无用的类。
  13. -XX:SoftRefLRUPolicyMSPerMB:用于设置软引用对象的LRU策略的时间限制。默认值为1000,表示每MB内存空间可以存活1秒钟的软引用对象。可以通过设置-XX:SoftRefLRUPolicyMSPerMB参数来调整软引用对象的LRU策略,从而影响软引用对象的回收策略和内存占用。
  14. -XX:PretenureSizeThreshold:用于设置对象在新生代内存区域中直接进入老年代内存区域的阈值大小。默认值为0,表示禁用直接进入老年代。
  15. -XX:TLABWasteTargetPercent:用于设置线程本地分配缓冲区(Thread Local Allocation Buffer, TLAB)的浪费阈值百分比。默认值为1,表示线程本地分配缓冲区中浪费的空间不能超过总空间的1%。
  16. -XX:+CollectGen0First:用于控制JVM在进行Full GC时是否先回收新生代内存区域。

元数据设置参数

  1. -XX:MetaspaceSize:设置元数据区初始大小。
  2. -XX:MaxMetaspaceSize:设置元数据区最大大小。
  3. -XX:MinMetaspaceFreeRatio:设置元数据区最小自由空间比率。
  4. -XX:MaxMetaspaceFreeRatio:设置元数据区最大自由空间比率。

JIT设置参数

垃圾收集器设置参数

参数名称 含义 默认值
-XX:+UseParallelGCFull GC采用parallel MSC 选择垃圾收集器为并行收集器.此配置仅对年轻代有效.即上述配置下,年轻代使用并发收集,而年老代仍旧使用串行收集.
-XX:+UseParNewGC 设置年轻代为并行收集  可与CMS收集同时使用JDK5.0以上,JVM会根据系统配置自行设置,所以无需再设置此值
-XX:ParallelGCThreads 并行收集器的线程数 此值最好配置与处理器数目相等 同样适用于CMS
-XX:+UseParallelOldGC 年老代垃圾收集方式为并行收集(Parallel Compacting)  这个是JAVA 6出现的参数选项
-XX:MaxGCPauseMillis 每次年轻代垃圾回收的最长时间(最大暂停时间)  如果无法满足此时间,JVM会自动调整年轻代大小,以满足此值.
-XX:+UseAdaptiveSizePolicy 自动选择年轻代区大小和相应的Survivor区比例  设置此选项后,并行收集器会自动选择年轻代区大小和相应的Survivor区比例,以达到目标系统规定的最低相应时间或者收集频率等,此值建议使用并行收集器时,一直打开.
-XX:GCTimeRatio 设置垃圾回收时间占程序运行时间的百分比 公式为 1/(1+n)
-XX:+ScavengeBeforeFullGCFull GC前调用YGCtrue Do young generation GC prior to a full GC.

CMS相关参数

  1. -XX:+UseConcMarkSweepGC:使用CMS内存收集
  2. -XX:+AggressiveHeap :用于启用一个基于性能的堆内存配置。启用该参数后,JVM会根据当前系统的硬件配置和内存使用情况来自动调整堆内存的大小和垃圾回收策略,以达到最佳的性能和内存利用率。
  3. -XX:CMSFullGCsBeforeCompaction :多少次后进行内存压缩
  4. -XX:+CMSParallelRemarkEnabled:降低标记停顿
  5. -XX+UseCMSCompactAtFullCollection:在FULL GC的时候, 对年老代的压缩
  6. -XX:+UseCMSInitiatingOccupancyOnly:使用手动定义初始化定义开始CMS收集
  7. -XX:CMSInitiatingOccupancyFraction=70:使用cms作为垃圾回收使用70%后开始CMS收集

GC日志设置参数

  1. -XX:+PrintGC:输出形式: [GC 118250K->113543K(130112K), 0.0094143 secs]
    [Full GC 121376K->10414K(130112K), 0.0650971 secs]
  2. -XX:+PrintGCDetails:输出形式:[GC [DefNew: 8614K->781K(9088K), 0.0123035 secs] 118250K->113543K(130112K), 0.0124633 secs]
    [GC [DefNew: 8614K->8614K(9088K), 0.0000665 secs][Tenured: 112761K->10414K(121024K), 0.0433488 secs] 121376K->10414K(130112K), 0.0436268 secs]
  3. -XX:+PrintGCTimeStamps
  4. -XX:+PrintGC:PrintGCTimeStamps:可与-XX:+PrintGC -XX:+PrintGCDetails混合使用
    输出形式:11.851: [GC 98328K->93620K(130112K), 0.0082960 secs]
  5. -XX:+PrintGCApplicationStoppedTime:打印垃圾回收期间程序暂停的时间.可与上面混合使用
  6. -XX:+PrintGCApplicationConcurrentTime:打印每次垃圾回收前,程序未中断的执行时间.可与上面混合使用
  7. -XX:+PrintHeapAtGC :打印GC前后的详细堆栈信息
  8. -Xloggc:filename:把相关日志信息记录到文件以便分析. 与上面几个配合使用
  9. -XX:+PrintClassHistogram
  10. -XX:+PrintTLAB
  11. -XX:+PrintTenuringDistribution:查看每次minor GC后新的存活周期的阈值

其他

  1. -XX:+UseFastAccessorMethods:用于启用快速访问器方法。快速访问器方法是一种优化技术,可以通过直接访问对象的字段,而不是通过getter和setter方法来访问对象的属性,从而提高访问对象的属性的效率。参数为true来启用快速访问器方法。需要注意的是,启用快速访问器方法可能会影响程序的可维护性和扩展性,因为它会暴露对象的内部实现细节,从而使得代码更加依赖于对象的具体实现。因此,需要根据具体的应用场景和需求进行选择和调整。
  2. -XX:+DisableExplicitGC:关闭System.gc()
  3. -XX:+UseBiasedLocking:锁机制的性能改善
  4. -XX:MaxDirectMemorySize:设置直接内存最大大小

实战配置

待后续更新

猜你喜欢

转载自blog.csdn.net/BASK2312/article/details/131359781