美文网首页
05_内存溢出_分析

05_内存溢出_分析

作者: 王康健_0124 | 来源:发表于2019-03-25 00:10 被阅读0次

什么是堆Dump

堆Dump是反应Java堆使用情况的内存镜像,其中主要包括系统信息、虚拟机属性、完整的线程Dump、所有类和对象的状态等。 一般,在内存不足、GC异常等情况下,我们就会怀疑有内存泄露。这个时候我们就可以制作堆Dump来查看具体情况。
当我们在做压测的时候,如果遇到服务器返回

outOfMemoryError 年老代内存不足。
outOfMemoryError:PermGen Space 永久代内存不足。
outOfMemoryError:GC overhead limit exceed 垃圾回收时间占用系统运行时间的98%或以上

这说明你的jvm中堆的内存不足,GC无法进行回收
这个时候我们就需要去分析因为是因为说明原因造成的!

注:当有内存溢出,程序无法访问的时候,不要赶紧去重启服务器,首先我们可以把堆中的信息dump下来

这里介绍一下jmap这个命令:

jmap -dump:将内存使用的详细情况输出到文件

  • 这个命令执行,JVM会将整个heap的信息dump写入到一个文件,heap如果比较大的话,就会导致这个过程比较耗时,并且执行的过程中为了保证dump的信息是可靠的,所以会暂停应用。

linux中输入jmap查看帮助文档,关于jmap -dump给了详细的example,我们只需要拷贝一下,然后把pid改成tomcat启动的进程号就行

例:
先查看启动的tomcat进程号:ps -ef|grep tomcat


执行:jmap -dump:live,format=b,file=heap.bin 1163

会在当前的目录下面生成一个heap.bin文件,这样就把堆中的信息dump下来,然后可以利用eclipse的mat插件进行分析
mat下载地址
提取码:6j78

然后file--open file 找的从linux中下载到本地的heap.bin文件(具体的使用方法就不教了,网上可自行看一下)

也可以使用 jhat 打开刚刚dump下来的文件,主要是用来分析java堆的命令,可以将堆中的对象以html的形式显示出来,包括对象的数量,大小等等,并支持对象查询语言。:

执行:jhat heap.bin
启动一个http服务,端口要是7000,在浏览器中输入本机的ip,加上端口号7000
Started HTTP server on port 7000

jhat详细介绍:https://www.cnblogs.com/baihuitestsoftware/articles/6406271.html

通过命令查看大对象

jmap -histo <pid>|less
进入命令要退出: q

  • 可得到如下包含对象序号、某个对象示例数、当前对象所占内存的大小、当前对象的全限定名,

如下图:

查看对象数最多的对象,并按降序排序输出:
执行:jmap -histo <pid>|grep tomcat|sort -k 2 -g -r|less

查看占用内存最多的最象,并按降序排序输出:
执行:jmap -histo <pid>|grep tomcat|sort -k 3 -g -r|less

结果如图

友情提示:jmap -histo:live pid>a.log,可以先将命令结果重定向到一个文件中,在一段时间后,使用文本对比工具,可以对比出GC回收了哪些对象!
#instance 是对象的实例个数 
#bytes 是总占用的字节数 
class name 对应的就是 Class 文件里的 class 的标识 
B 代表 byte
C 代表 char
D 代表 double
F 代表 float
I 代表 int
J 代表 long
Z 代表 boolean
前边有 [ 代表数组, [I 就相当于 int[]
对象用 [L+ 类名表示

jstat -gcutil 实时查看堆运行情况
命令:jstat -gcutil 1163 2000 10
jstat -gcutil pid 多久展现一次 展现多少次

S0:第一个幸存区的使用大小
S1:第二个幸存区的使用大小
E:伊甸园区的使用大小
O:老年代使用大小
M:方法区使用大小
CCS:压缩类空间使用大小
YGC:年轻代垃圾回收次数
YGCT:年轻代垃圾回收消耗时间
FGC:老年代垃圾回收次数
FGCT:老年代垃圾回收消耗时间
GCT:垃圾回收消耗总时间

当FGC一直在增加,O达到了95%或者100%的时候,由于内存不住,会执行fullGC回收内存,但是由于老年区的内存被占用无法进行回收,两者冲突就会不断的执行FGC,增加FQC的次数!这个时候你就需要去排查

性能问题查找

1、发现问题
1)、使用uptime命令查看CPU的Load情况,Load越高说明问题越严重;
2)、使用jstat查看FGC发生的频率及FGC所花费的时间,FGC发生的频率越快、花费的时间越高,问题越严重;

总结
1.如果程序内存不足或者频繁GC,很有可能存在内存泄露情况,这时候就要借助Java堆Dump查看对象的情况。
2.要制作堆Dump可以直接使用jvm自带的jmap命令
3.可以先使用jmap -heap命令查看堆的使用情况,看一下各个堆空间的占用情况。
4.使用jmap -histo:[live]查看堆内存中的对象的情况。如果有大量对象在持续被引用,并没有被释放掉,那就产生了内存泄露,就要结合代码,把不用的对象释放掉。
5.也可以使用 jmap -dump:format=b,file=<fileName>命令将堆信息保存到一个文件中,再借助jhat命令查看详细内容
6.在内存出现泄露、溢出或者其它前提条件下,建议多dump几次内存,把内存文件进行编号归档,便于后续内存整理分析。
7.在用cms gc的情况下,执行jmap -heap有些时候会导致进程变T,因此强烈建议别执行这个命令,如果想获取内存目前每个区域的使用状况,可通过jstat -gc或jstat -gccapacity来拿到。

相关文章

  • 05_内存溢出_分析

    什么是堆Dump 堆Dump是反应Java堆使用情况的内存镜像,其中主要包括系统信息、虚拟机属性、完整的线程Dum...

  • JVM学习系列学习七

    5:实战:内存溢出的定位与分析 内存溢出在日常工作中,这个错误很容易遇到。遇到内存溢出,首先我们需要快速定位内存溢...

  • Memory Analyzer

    Memory Analyzer用来分析内存溢出dump日志

  • 内存优化

    内存优化主要是分析内存泄露和内存溢出。将从内存是怎么分配,内存怎么出现泄露和溢出,用工具判断什么情况出现泄露,找出...

  • Java开发

    JVM 内存溢出实例 - 实战 JVM(二) 介绍 JVM 内存溢出产生情况分析Java - 注解详解 详细介绍 ...

  • JVM架构和GC垃圾回收机制详解

    原文JVM架构图分析 下图:参考网络+书籍,如有侵权请见谅(想了解Hadoop内存溢出请看:Hadoop内存溢出(...

  • iOS 项目性能分析(用Xcode进行内存分析)

    项目中的性能分析分为两种 先解释一下什么内存泄漏和内存溢出 内存泄漏:该释放的时候没有释放内存溢出:简单说就是内存...

  • Android 内存泄漏分析

    Android 内存泄漏分析 Hi,这几天应用内存溢出了,所有我学习了下内存溢出相关的知识点,以下的知识点都来自网...

  • JAVA内存溢出分析

    开发多年,最近2年,经常遇到其他同行或者别的项目组在业务测试环境上,甚至还有的在生产环境上出现(多数是后台管理系统...

  • 【JVM】内存溢出分析

    一 内存溢出概述 都有发生内存溢出异常(OutOfMemoryError,简称OOM)的可能。 内存溢出和内存泄漏...

网友评论

      本文标题:05_内存溢出_分析

      本文链接:https://www.haomeiwen.com/subject/vmeuvqtx.html