JVM内存排查

方法一

jmap -histo:live 18311 | head -20  用jmap查看存活的对象情况

定位到代码

现在已经知道了是HashTable的问题,那么就要定位出什么代码引起的

接下来自然要看看是什么代码往HashTable里疯狂的put数据,于是用神器btrace跟踪Hashtable.put调用的堆栈。

首先写btrace脚本TracingHashTable.java:

 
  1. import com.sun.btrace.annotations.*;

  2. import static com.sun.btrace.BTraceUtils.*;

  3.  
  4. @BTrace

  5. public class TracingHashTable {

  6. /*指明要查看的方法,类*/

  7. @OnMethod(

  8. clazz="java.util.Hashtable",

  9. method="put",

  10. location=@Location(Kind.RETURN))

  11. public static void traceExecute(@Self java.util.Hashtable object){

  12. println("调用堆栈!!");

  13. jstack();

  14. }

  15. }

然后运行:
bin/btrace -cp build 4947 TracingHashTable.java

看到有大量类似下图的调用堆栈

 

可以看出是在接收到消息后查询入库的代码造成的,业务方法调用ibatis再到mysql jdbc驱动执行statement时put了大量的属性到HashTable中。

 

方法二

jmap命令可以获得运行中的jvm的堆的快照,从而可以离线分析堆,以检查内存泄漏,检查一些严重影响性能的大对象的创建,检查系统中什么对象最多,各种对象所占内存的大小等等

命令格式

jmap [options] pid -dump:[live,]format=b,file=

-dump堆到文件,live指明是活着的对象,file指定文件名,pid 是java进程id

通过这个命令可以查看系统内存情况,但受限于所展示的内存通过能够保存到几十兆以上的的文件内容,手工分析查看实在是太过辛苦,所以也未能解决。

jmap -dump:format=b,file=jmap.hprof 32460

在利用Java堆分析工具分析

你可能感兴趣的:(JVM内存排查)