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 ” 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中可分析出线程是否存在死锁及其他错误。

原文地址:https://www.cnblogs.com/NiceTime/p/6665583.html