前言
- 前些日子小编接到一个新活,生产环境的服务器内存经常爆满,还没有用多长时间了,内存就剩不下多少了,经理于是让我分析了一下JVM内存,找一找哪个对象占用内存大,有没有内存泄露的地方,以及哪个线程占用资源多等等。
使用Jmap在线上分析
- 首先,小编用jvm自带的工具jmap查了一下tomcat分配堆栈内存的一些信息。检查一下堆中老年代和新生代的使用情况,排查一下是否是分配的内存过少导致。过程如下
1、用jps命令将服务器上的java进程的pid查出来
jps
因为tomcat也是java进程,如果一个机器上就运行一个tomcat的话,用jps命令查看tomcat的进程pid是非常方便的。
或者用ps命令查看端口号
ps aux | grep tomcat
2、再用jmap命令,打印tomcat堆栈信息
jmap -heap pid
如果内存不够用,则多给tomcat分配点内存。
3、用jmap命令,查看哪个对象占用的内存多
jmap -histo:live pid | more
内存快照分析
- 上面的都是一些运维的基础命令,如果运用上面的简单命令不能排查出问题来的话,我们还可以使用工具来分析内存快照。这个工具就是MAT(Memory Analyzer Tool),这里小编简单介绍一下 Eclipse Memory Analyzer,用它可以来分析内存快照。
获取内存快照(dump下来)
第一种方式,用jmap命令
jmap -dump:format=b,file=heap.bin pid
- format=b 的意思是dump出来的内存快照文件是二进制文件
- file=heap.bin的意思是文件名称是 heap.bin
- pid 就是tomcat或者java进程的pid
第二种方式
如果程序运行在tomcat中,可以在bin/catalina.sh中配置参数,等到tomcat报OOM(out of memory)的时候自动将内存快照dump下来。
JAVA_OPTS="$JAVA_OPTS -server -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=D:\heapdump"
- 上面两个参数的意思是一个开启dump文件,另一个是当dump内存快照的地址。
MAT使用简单教程
这里小编放一个简书的链接吧,对于MAT入门来说,够用了。
http://www.jianshu.com/p/d8e247b1e7b2
小结
- 注意:在用jmap命令dump内存快照时,为了保证快照的完整行,tomcat会停止响应一段时间,假如读者想直接dump生产环境上的内存快照的话,最后先用
jmap-heap pid
查一下tomcat中堆栈占用的内存大小,如果tomcat占用内存特别大的话,dump内存快照时很耗时,用户体验度不好,还有检查服务器的磁盘是否还够用,别dump下来的东西磁盘放不下。