梳理JVM内存结构、GC、类加载、AOP编程及性能监控——11

107 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第47天,点击查看活动详情

调优

命令行工具(以Linux场景进行详解)

  • GC监控:

./jstat -gc pid 3s对pid GC每隔3s进行监控

  • 谁动了我的CPU
  1. top查看CPU使用情况,或通过CPU使用率收集,找到CPU占用率高Java进程,假设其进程编号为pid;
  2. 使用top -Hp pid(或ps -Lfp pid或者ps -mp pid -o THREAD,tid,time)查看pid进程中占用CPU较高的线程,假设其编号为tid;
  3. 使用Linux命令,将tid转换为16进制数,printf '%0x\n' tid,假设得到值txid;
  4. 使用jstack pid | grep txid查看线程CPU占用代码,然后根据得到的对象信息,去追踪代码,定位问题。
  • 死锁

另外,jstack -l long listings,会打印出额外的锁信息,在发生死锁时可以用jstack -l pid来观察锁持有情况。

  • Memory
  1. 查看java 堆(heap)使用情况jmap -J-d64 -heap pid,其中-J-d64为64位机器标识,启动
  2. 查看堆内存(histogram)中的对象数量及大小jmap -J-d64 -histo pid;而查看存活对象-histo:live,这个命令执行,JVM会先触发gc,然后再统计信息。 如果有大量对象在持续被引用,并没有被释放掉,那就产生了内存泄露,就要结合代码,把不用的对象释放掉。 其中class name中B 代表 byte,C 代表 char,D 代表 double,F 代表 float,I 代表 int,J 代表 long,Z 代表 boolean,前边有 [ 代表数组, [I 就相当于 int[],对象用 [L+ 类名表示
  3. 程序内存不足或者频繁GC,很可能存在内存泄露将内存使用的详细情况输出到文件,执行命令:jmap -J-d64 -dump:format=b,file=heapDump pid;然后用jhat命令可以参看 jhat -port 5000 heapDump

--

内存泄漏OOM,通常做法: 方法1. 首先配置JVM启动参数,让JVM在遇到OutOfMemoryError时自动生成Dump文件-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/path 方法2. 使用上面第3步进行进行分析; 方法3. 使用eclipse的MAT分析工具对dump文件进行分析

  1. 发现问题
  • 使用uptime命令查看CPU的Load情况,Load越高说明问题越严重;
  • 使用jstat查看FGC发生的频率及FGC所花费的时间,FGC发生的频率越快、花费的时间越高,问题越严重;
  1. 使用jmap -head 观察老年代大小,当快达到配置的阀值CMSInitiatingOccupancyFraction时,将对象导出进行分析;
  2. 对head中对象进行命令行排序分析:./jmap -J-d64 -histo pid | grep java | sort -k 3 -n -r | more按照bytes大小进行排序;数量最多排序将-k 3换成-k 2即可