本文共 4621 字,大约阅读时间需要 15 分钟。
实用JVM参数
1. JIT 编译参数
JIT(Just-In-Time)编译器, 可以在运行时将字节码编译成本地代码,从而提升函数的执行效率。
-XX:CompileThreshold为 JIT编译的阈值, 当函数的调用次数超过-XX:CompileThreshold时,JIT就将字节码编译成本地机器码。
在Client 模式下, XX:CompileThreshold 的取值为1500;
在Server 模式下, 取值是 10000.
JIT编译完成后, JVM便会使用本地代码代替原来的字节码解释执行。
为了内合理的设置JIT编译的阈值, 可以使用-XX:_CITime打印出JIT编译的耗时, 也可以使用-XX:+PrintCompilation 打印出JIT编译的信息。
看例子:
package com.oscar999.performance.JVMTune;public class TestJIT { static long i = 0; /** * @param args */ public static void testJIT(){ i++; } public static void main(String[] args) { // TODO Auto-generated method stub for(int j=0;j<1488;j++) testJIT(); long end = System.currentTimeMillis(); }}使用命令运行:
java -XX:CompileThreshold=1500 -XX:+PrintCompilation -XX:+CITime com.oscar999.performance.JVMTune.TestJIT
将以上循环次数从1488 换成 1588, 再运行可以看到, 大于 1500时, 做了编译成本地码的动作。
2. 堆快照(堆Dump)
获得程序的堆快照文件有很多方法, 比较常用的取得堆快照文件的方法是使用-XX:+HeapDumpOnOutOfMemoryError 参数在程序发生OOM时,导出应用程序的当前堆快照。
-Xmx10m -XX:+HeapDumpOnOutOfMemoryError -XX:heapDumpPath=C:\m.hprof
3. 错误处理
当系统发生OOM错误时,虚拟机在错误发生时运行一段第三方脚本, 比如, 当OOM发生时,重置系统
-XX:OnOutOfMemoryError=c:\reset.bat
4. 获取GC信息
JVM虚拟机也提供了许多参数帮助开发人员获取GC信息。
可以使用 -verbose:gc 或者 -XX:+PrintGC.
如果要获得更加详细的信息, 可以使用 -XX:+PrintGCDetails.
如果需要查看新生对象晋升老年代的实际阈值, 可以使用参数 -XX:+PrintTenuringDistribution
如果需要查看GC与实际程序相互执行的耗时, 可以使用 -XX:+PrintGCApplicationt-StoppedTime 和 -XX:+PrintGCApplicationConcurrentTime参数。
可以使用 -Xloggc 参数指定GC日志的输出位置。 如 -Xloggc:C:\gc.log
5. 类和对象跟踪
-XX:+TraceClassLoading 参数用于跟踪类加载情况
-XX:+TraceClassUnloading 用于跟踪类卸载情况。
除了类的跟踪, JVM 还提供了 -XX:+PrintClassHistogram 开关用于打印运行时实例的信息。 当此开关被打开时, 当Ctrl+Break 被按下, 会输出系统内类的统计信息。
6. 控制GC
-XX:+DisableExplicitGC 选项用于禁止显式的GC操作, 即禁止在程序中使用System.gc() 触发Full GC.
-Xnoclassgc 参数, 不回收类, 进而提升GC的性能。
-Xincgc, 一旦启用这个参数,系统便会进行增量式的 GC. 增量式的GC使用特定算法让GC线程和应用程序线程交叉执行,从而减小应用程序因GC而产生的停顿时间。
7. 选择类校验器
在JDK1.6中默认开启新的类校验器,加速类的记载, 可以使用 -XX:-UseSplitVerifier参数指定使用旧的类校验器。
如果新的校验器校验失败,可以使用老的校验器再次校验。可以使用开关 -XX:-FailOverToOldVerifier关闭再次校验的功能
8. Solaris 下线程控制
在 Solaris 下, JVM提供了几个用于线程控制的开关
-XX:+UseBoundTreads: 绑定所有用户线程到内核线程, 减少线程进入饥饿状态的次数
-XX:+UserLWPSynchronization: 使用内核线程替换线程同步
-XX:+UserVMInterruptibleIO: 运行运行时中断线程。
9.. 使用大页
对同样大小的内存空间, 使用大页后, 内存分页的表现就会减少, 从而可以提升CPU从虚拟内存地址映射到物理内存地址的能力。 在支持大页的操作系统中,使用JVM参数让虚拟机使用大页,从而提升系统性能。
-XX:+UserlargePages: 启用大页
-XX:LargePageSizeInBytes: 指定大页的大小
10. 压缩指针
在64位虚拟机上, 应用程序所占内存的大小要远远超出其32位版本(约1.5 倍左右)。这是因为64位系统拥有更宽的寻址空间, 与32位系统相比,指针对象的长度进行了翻倍。为了解决这个问题,
64位的JVM虚拟机可以使用 -XX:+UseCompressedOops参数打开指针压缩,从一定程度上减少内存的消耗,可以对以下指针进行压缩:
Class的属性指针
对象的属性指针
普通对象数组的每个元素指针
实战JVM调优
Tomcat 启动加速
使用 startup.bat 启动Tomcat 服务器时, start.bat 调用了bin 目录下的calalina.bat 文件。
设置环境变量CATALINA_OPTS 或者JAVA_OPTS都可以设置tomcat 的JVM优化参数。
set CATALINA_OPTS=-Xloggc:gc.log -XX:+PrintGCDetails
为了减少Minor GC的次数, 增大新生代
set CATALINA_OPTS=%CATALINA_OPTS% -Xmx32M -Xms32M
禁用显示GC
set CATALINA_OPTS=%CATALINA_OPTS% -XX:+DisableExplicitGC
在堆内存不变的前提下,为了能进一步减少Minor GC的次数,可以扩大新生代的大小
set CATALINA_OPTS=%CATALINA_OPTS% -XX:NewRation=2
为了加快Minor GC的速度,在多核计算机上可以考虑使用新生代并行回收收集器,加快Minor GC 的速度
set CATALINA_OPTS=%CATALINA_OPTS% -XX:+UseParallelGC
由于JVM虚拟机在加载类时,处于完全考虑,会对Class进行校验和认证,如果类文件是可信任的, 为了加快程序的运行速度,也可以考虑禁用这些效应:
set CATALINA_OPTS=%CATALINA_OPTS% -Xverify:none
JMeter介绍和使用
JMeter是Apache 下基于Java 的一款性能测试和压力测试工具。它基于Java 开发,可对HTTP 服务器和FTP服务器,甚至是数据库进行压力测试。
线程组将模拟用户线程访问Tomcat 服务器。
在线程组之下,需要给线程组分配相应的采样器, 比如HTTP请求, FTP请求,数据库连接等。
除线程组和采样器外,最后还需要一份测试报告。JMeter可以给出各种形式或侧重于各个方面的测试报告。
调优前:
从以上图中可以看到, 最大堆为 256MB, 但在实际使用中, 只使用了50MB.因此, 引起了频繁的GC.
在永久区,最大为64MB,而实际使用时,初始值约在10MB左右,并经历一次扩容,达到19MB左右,基本稳定在19MB.
调优过程
为了减少GC次数, 可以使用合理的堆大小和永久区大小。这里将堆大小设置为512MB, 永久区使用32MB, 同时, 禁用显示GC, 并去掉类校验。参数如下:
set CATALINA_OPTS=%CATALINA_OPTS% "-Xmx512M"set CATALINA_OPTS=%CATALINA_OPTS% "-Xms512M"set CATALINA_OPTS=%CATALINA_OPTS% "-XX:PermSize=32M"set CATALINA_OPTS=%CATALINA_OPTS% "-XX:MaxPermSize=32M"set CATALINA_OPTS=%CATALINA_OPTS% "-XX:+DisableExplicitGC"set CATALINA_OPTS=%CATALINA_OPTS% "-Xverify:none"为了进一步提高系统的吞吐量, 可以尝试使用并行回收收集器代替串行收集器。
set CATALINA_OPTS=%CATALINA_OPTS% "-Xmx512M"set CATALINA_OPTS=%CATALINA_OPTS% "-Xms512M"set CATALINA_OPTS=%CATALINA_OPTS% "-XX:PermSize=32M"set CATALINA_OPTS=%CATALINA_OPTS% "-XX:MaxPermSize=32M"set CATALINA_OPTS=%CATALINA_OPTS% "-XX:+DisableExplicitGC"set CATALINA_OPTS=%CATALINA_OPTS% "-Xverify:none"set CATALINA_OPTS=%CATALINA_OPTS% -XX:+UseParallelGCset CATALINA_OPTS=%CATALINA_OPTS% -XX:+UseParallelOldGCset CATALINA_OPTS=%CATALINA_OPTS% -XX:ParallelGCThreads=8总结一下: JVM调优的主要过程有:
确定堆内存大小(-Xmx, -Xms)
合理分配新生代和老生代(-XX:NewRation, -Xmn, -XX:SurvivorRatio)
确定永久区大小: -XX:Permsize, -XX:MaxPermSize
选择垃圾收集器
对垃圾收集器进行合理的设置
除此之外,禁用显示GC(-XX:+DisableExplicitGC), 禁用类元数据回收(-Xnoclassgc), 禁用类验证(-Xverfy:none)等设置, 对提升系统性能也有一定的帮助。
转载地址:https://oscar.blog.csdn.net/article/details/47271531 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!