1、堆内存调优
使用场景:调整JVM的堆内存可以帮助避免内存溢出,提高垃圾回收的效率。
java -jar -Xms4g -Xmx4g heapTest-0.0.1-SNAPSHOT.jar
-Xms 参数用于设置JVM启动时的初始堆大小。
-Xmx 参数用于设置JVM可以使用的最大堆内存大小。
-Xmn 参数用于设置年轻代大小。
2、垃圾回收器选择和调优
使用场景:合适的垃圾回收器能够提高应用的响应速度和吞吐量。
# 使用G1垃圾回收器
java -XX:+UseG1GC -jar your-application.jar
UseG1GC 参数用于启用G1垃圾回收器,它是适用于大堆内存并且需要低延迟的场景。
3、线程堆栈大小调优
使用场景:合理的线程堆栈大小有助于提高线程创建和管理的效率。
java -Xss1m -jar your-application.jar
-Xss 参数用于设置每个线程的堆栈大小。
线程堆栈大小应根据应用的实际需求调整,避免过大消耗过多内存,或过小导致栈溢出。
4、调整年轻代和老年代的比例
使用场景:调整年轻代和老年代的比例可以根据应用的特性来优化垃圾回收行为,影响整体的垃圾回收效率。
# 设置年轻代和老年代的比例为1:2
java -XX:NewRatio=2 -jar your-application.jar
# 解释
-XX:NewRatio=2 # 设置老年代与年轻代的比例为2,即老年代是年轻代大小的两倍
-XX:NewRatio 参数用于设置老年代和年轻代的大小比例。
如果你的应用长时间运行并且主要进行老年代垃圾回收,增大这个比例可能会有帮助。
5、设置Survivor区比例
使用场景:在年轻代中,Eden区和Survivor区的比例会影响对象晋升老年代的速度。根据应用的对象生命周期调整这个比例,可以优化内存管理。
# 设置Eden区和Survivor区的比例
java -XX:SurvivorRatio=8 -jar your-application.jar
# 解释
-XX:SurvivorRatio=8 # 设置Eden区与一个Survivor区的大小比例为8,即Eden是Survivor的8倍
-XX:SurvivorRatio 参数定义了年轻代中Eden区与Survivor区的大小比例。
适当调整这个比例可以优化对象在年轻代的存活时间,减少老年代的压力。
6、启用GC日志和调试
使用场景:启用GC日志可以帮助你监控垃圾回收过程,并对性能问题进行诊断。
# 启用GC日志
java -XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:gc.log -jar your-application.jar
# 解释
-XX:+PrintGCDetails # 打印详细的GC日志
-XX:+PrintGCDateStamps # 在GC日志中包含时间戳
-Xloggc:gc.log # 指定GC日志输出文件
启用这些GC日志参数可以提供关于垃圾回收的详细信息,包括每次GC的类型、时间、持续时间以及内存回收情况。
这些信息对于理解应用的内存使用模式和调整GC策略非常有用。
压测工具 AB
Ab(ApacheBench) 测试工具是 Apache 提供的一款测试工具,具有简单易上手的特点,在测试 Web 服务时非常实用。 ab 一般都是在 Linux 上用。
安装非常简单,只需要在 Linux 系统中输入 yum -y install httpd-tools 命令,就可以了。
使用 AB 进行压力测试:
ab -c 10 -n 100000
参数的含义:
-n:总请求次数(最小默认为 1);
-c:并发次数(最小默认为 1 且不能大于总请求次数,例如:10 个请求,10 个并发,实际就是 1 人请求 1 次);
-p:post 参数文档路径(-p 和 -T 参数要配合使用);
-T:header 头内容类型(此处切记是大写英文字母 T);
统计 GC 的情况:jstat -gc 8404 5000 20 | awk '{print $13,$14,$15,$16,$17}
表示对jvm进程Id为8404的进程,每个5秒统计一次gc信息,统计20次结束
GC 频率
高频的 FullGC 会给系统带来非常大的性能消耗,虽然 MinorGC 相对 FullGC 来说好了许多,但过多的 MinorGC 仍会给系统带来压力。
7、设置最大停顿时间目标
使用场景:当应用需要低延迟时,可以设置JVM的最大停顿时间目标,这有助于减少垃圾回收造成的延迟。
# 设置最大停顿时间目标
java -XX:MaxGCPauseMillis=200 -jar your-application.jar
# 解释
-XX:MaxGCPauseMillis=200 # 设置垃圾回收的最大停顿时间为200毫秒
-XX:MaxGCPauseMillis 参数用于告诉垃圾回收器尽量在指定的时间内完成垃圾回收。
这对于需要低延迟的应用特别有用,如实时交互系统。
9、调整大对象直接进入老年代的阈值
使用场景:对于那些创建了大量大对象的应用,调整这些大对象直接晋升到老年代的阈值,可以减少年轻代垃圾回收的次数。
# 设置大对象直接进入老年代的阈值
java -XX:PretenureSizeThreshold=1048576 -jar your-application.jar
# 解释
-XX:PretenureSizeThreshold=1048576 # 设置大对象(大于1MB)直接在老年代分配
-XX:PretenureSizeThreshold 参数用于设置一个大小阈值,超过这个大小的对象将直接在老年代分配内存。
这有助于减少大对象在年轻代中的分配和复制,特别是对于那些频繁创建和销毁大对象的应用。
10、调整GC日志文件的回滚和大小限制
使用场景:当需要长时间收集GC日志进行分析时,管理日志文件的大小和回滚非常重要,以避免消耗过多磁盘空间。
# 设置GC日志文件的回滚和大小限制
java -Xloggc:gc.log -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=10M -jar your-application.jar
# 解释
-Xloggc:gc.log # 指定GC日志输出文件
-XX:+UseGCLogFileRotation # 启用GC日志文件的回滚
-XX:NumberOfGCLogFiles=5 # 保留最近的5个GC日志文件
-XX:GCLogFileSize=10M # 每个GC日志文件的最大大小为10MB
这些参数结合使用可以有效管理GC日志文件的大小和数量,避免单个日志文件过大,同时保留足够的历史数据供分析。
12、使用并行垃圾回收器
使用场景:对于需要高吞吐量的应用,如批处理或后台处理系统,使用并行垃圾回收器可以提高效率。
# 使用并行垃圾回收器
java -XX:+UseParallelGC -XX:ParallelGCThreads=4 -jar your-application.jar
# 解释
-XX:+UseParallelGC # 启用并行垃圾回收器
-XX:ParallelGCThreads=4 # 设置垃圾回收时使用的线程数为4
并行垃圾回收器在执行GC时会使用多个线程,这可以在多核处理器上显著提高垃圾回收的效率。
ParallelGCThreads 参数用于指定执行垃圾回收时并行线程的数量,通常设置为与CPU核心数相同。
结论
JVM调优是一项需要根据应用特性和运行环境细致调整的任务。上述的调优方法和参数只是众多可能性中的一小部分。成功的JVM调优需要对应用的行为有深刻的理解,以及对JVM工作原理的充分了解。
在实际操作中,建议逐步调整参数,并结合性能监控工具来评估调优效果。记住,随着应用的发展和JVM技术的进步,调优是一个持续的过程。