JVM性能分析和调优方向
Posted 新美好时代
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JVM性能分析和调优方向相关的知识,希望对你有一定的参考价值。
1.1合理配置参数
1.1. JVM内存结构介绍
jvm内存=堆内存+非堆内存
堆内存=新生代+年老代 新生代=1个Eden区+2个survivor区
非堆内存=持久代+代码缓存
配置项的新参考jdk版本,jdk版本不同,有的配置项没有,可参考oracle官方网站
http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html
-server:服务器模式,该参数放置在配置项的首位置
-Xms:堆的初始大小,单位MB 配置-Xms与-Xmx一致,为可用内存的80%
-XmX:堆的最大大小,单位MB
-Xmn:新生代的初始大小,单位MB 为堆大小的3/8
当业务中有数据量很大的文件需要导出时,需要调整以下2个参数的值,可避免出现OOM
-XX:PermSize:持久代的初始大小,单位MB 为物理内存的1/64
-XX:MaxPermSize:持久代的最大大小,单位MB 为物理内存的1/4
-Xss:线程栈的大小,单位MB,如要调整,推荐1~2MB
-XX:NewRatio:年老代与新生代的比值
-XX:SurvivoRatio:Eden区与Survivo区的比值
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=./java_pid<pid>.hprof
在JVM崩溃时,可以打印出heap dump
-XX:+AggressiveOpts 加快编译
-Djava.awt.headless=true 启用该项,可解决报表不兼容的问题
-XX:+UseCMSCompactAtFullCollection:使用并发收集器时,开启对年老代的压缩,启用该项可对存活对象进行整理,可减少内存碎片
-XX:+UseInitiatingOccupancyFraction=80:年老代占满80%时,开始进行CMS的垃圾回收
-XX:+DisableExplicitGC:不允许显示调用system.gc()
-XX:+UseGCOverheadLimit:当垃圾回收耗费了98%的时间,但回收的内存不到2%时,jvm认为发生了OOM,可以起到预警的作用。
1.GC过程介绍
2.1. GC运行原理介绍
当1个对象生成后,会被放在新生代区域中的Eden区(young中的Eden),如果Eden区满,会触发young gc,不能被回收的对象放入s区(s0或s1),当s(s0或s1)区满后,对象会被放入年老代区域(old),如果old区满了,触发full gc,对象被放到持久代区(perm区)。
建议:尽量不要频繁的触发full gc,young gc频繁属于正常现象。
2.2. GC收集算法介绍
推荐设置为:并发标记清除收集器(CMS):-XX:+UseConcMarkSweepGC,多线程回收、垃圾收集时减少了卡顿时间、减少了fullgc的概率,适用于响应时间大型系统。
Serial GC(-XX:+UseSerialGC):在client模式下使用,性能最差。
Parallel GC(-XX:+UseParallelGC):多线程收集年轻代中的无效和不使用的对象,单线程收集年老代中的无效和不使用的对象
Parallel Old GC(-XX:+UseParallelOldGC):多线程收集年轻代和年老代中的无效和不使用的对象。
1.内存泄漏和系统超负荷
3.1. 内存泄漏和超负荷介绍
内存泄漏:由于错误的配置导致使用的资源无法被及时回收引起,可通过软件调优解决。
现象有:内存快要被占满,处于临界点;对应系统的日志中有出现OOM等关键字。
系统超负荷:系统中没有更多的可用资源引起,可通过更新硬件解决。
内存泄漏趋势图,其中多次GC后,多个低点的连线趋势为上升趋势,表明存在内存泄漏现象。
3.2. 常见内存泄漏介绍
3.2.1. 配置方面
1)年老代堆堆空间被占满,非常典型 异常有:java.lang.outofmemory java heap space
调整-Xms M -Xmx M 为可用内存的80% -Xmn M 为堆大小的3/8
free -m
可用内存=free+buffers+cached
2)持久代堆堆空间被占满,异常有:java.lang.outofmemory java perm space
调整-XX:PermSize= M -XX:MaxPermSize= M 1/64 1/4
3)线程栈异常:java.lang.stackoverflowerror stack size too small
调整-Xss=1M 推荐1~2M
4)系统内存被占满
java.lang.outofmemoryerror unable to create new native thread
加内存条,扩大内存大小;调整代码,减少线程的创建以降低对内存的消耗
3.2.2. 代码方面
1)对象无法回收(静态类型)
2)数据库连接没有被关闭
1.常用监控和分析命令
4.1. jps命令
查看运行于jvm上java进程的命令:jps -ml
4.2. jstat命令
查看jvm性能统计信息包括GC统计信息:jstat pid -gcutil 5s 5
4.3. jmap命令
查看堆内存映射信息:jmap
可打印指定java进程、核心文件、远程调用服务器的共享对象内存映射或堆内存细节
jmap -heap pid
jmap -histo:live pid
jmap -dump:live,format=b,file=./yyyy-mm-dd.hprof pid
4.4. jstack命令
查看线程堆栈跟踪的信息:jstack
可打印指定java进程、核心文件、远程调用服务器的线程堆栈的跟踪信息
4.5. 热点CPU定位
定位和分析热点CPU的进程
jps pid
top -Hp pid 或 ps -mp pid -o THREAD,tid,time
printf “%x\\n” tid
jstack pid |grep 16进制的tid -A 30
1.常用监控和分析工具
5.1. 监控tomcat
监控远程的tomcat服务,需要在catalina.sh中加入配置,可根据实际情况做优化配置
JAVA_OPTS="-Djava.awt.headless=true -Dfile.encoding=UTF-8
-server -XX:MinHeapFreeRatio=80 -XX:MaxHeapFreeRatio=80 -XX:ThreadStackSize=512
-XX:NewSize=128m
-XX:MaxPermSize=64m
-XX:NewRatio=4 -XX:SurvivorRatio=8
-XX:+AggressiveOpts -XX:+UseBiasedLocking
-XX:+UseConcMarkSweepGC -XX:+ScavengeBeforeFullGC
-XX:+PrintGCDetails -XX:+PrintGCTimeStamps -Xloggc:../logs/performance_gc.log
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=../logs/performance_heapdump.hprof"
加入配置的项。
CATALINA_OPTS="-Dcom.sun.management.jmxremote -Djava.rmi.server.hostname=服务器的IP地址
-Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.port=端口号"
5.2. 其他工具介绍
Jconsole:可监控本地和远程机器上CPU、堆内存及各分代区内存占用、类和线程使用情况,分析是否有死锁,支持垃圾回收。
Jvisualvm:可监控本地和远程机器上CPU、堆内存、类和线程使用情况,分析是否有死锁,支持垃圾回收、线程dump、堆dump及分析线程dump、堆dump、应用快照、profile快照文件,以便发现问题。通过jmx方式连接ip:port
MemoryAnalyzer:内存分析工具,可分析jvisualvm中堆dump产生的hprof文件及jcmd dump的文件,可在打开的dump文件的详情报告中,在Thread Stack中可分析出线程是否存在死锁及其他错误。
以上是关于JVM性能分析和调优方向的主要内容,如果未能解决你的问题,请参考以下文章