使用jmap和MAT分析JVM堆内存
来源:互联网 发布:南京水科院怎么样知乎 编辑:程序博客网 时间:2024/06/07 06:43
我的一台生产环境机器每次运行几天之后就会莫名其妙的宕机,分析日志之后发现在tomcat刚启动的时候内存占用比较少,但是运行个几天之后内存占用越来越大,通过jmap命令可以查询到一些大对象引用没有被及时GC,这里就要求解决内存泄露的问题。
Java的内存泄露多半是因为对象存在无效的引用,对象得不到释放,如果发现Java应用程序占用的内存出现了泄露的迹象,那么我们一般采用下面的步骤分析:
1. 用工具生成java应用程序的heap dump(如jmap)
2. 使用Java heap分析工具(如MAT),找出内存占用超出预期的嫌疑对象
3. 根据情况,分析嫌疑对象和其他对象的引用关系。
4. 分析程序的源代码,找出嫌疑对象数量过多的原因。
以下一步步的按照项目实例来操作,去解决内存泄露的问题。
1. 登录linux服务器,获取tomcat的pid,命令:
2. 利用jmap初步分析内存映射,命令:
第2行是我们业务系统的对象,通过这个对象的引用可以初步分析出到底是哪里出现了引用未被垃圾回收收集,通知开发人员优化相关代码。
3. 如果上面一步还无法定位到关键信息,那么需要拿到heap dump,生成离线文件,做进一步分析,命令:
4. 拿到heap dump文件,利用eclipse插件MAT来分析heap profile。
a. 安装MAT插件
b. 在eclipse里切换到Memory Analysis视图
c. 用MAT打开heap profile文件。
直接看到下面Action窗口,有4种Action来分析heap profile,介绍其中最常用的2种:
- Histogram:这个使用的最多,跟上面的jmap -histo 命令类似,只是在MAT里面可以用GUI来展示应用系统各个类产生的实例。
Shllow Heap排序后发现 Cms_Organization 这个类占用的内存比较多(没有得到及时GC),查看引用:
分析引用栈,找到无效引用,打开源码:
有问题的源码如下:
分析源码,定时任务定时调用,每次调用生成10个线程处理,而它又使用了非线程安全的List对象,导致List对象无法被GC收集,所以这里将List替换为CopyOnWriteArrayList 。- Dominator Tree:这个使用的也比较多,显示大对象的占用率。
同样的打开源码:
这里的HashMap也有问题:居然使用定时任务,在容器启动之后定时将数据放到Map里面做缓存?这里修改这部分代码,替换为使用memcached缓存即可。内存泄漏的原因分析,总结出来只有一条:存在无效的引用!良好的编码规范以及合理使用设计模式有助于解决此类问题。
- 使用jmap和MAT分析JVM堆内存
- 使用jmap和MAT分析JVM堆内存
- 使用jmap dump 分析JVM内存状态
- 使用jmap和MAT定位内存泄漏OOM
- 使用jmap和MAT定位内存泄漏OOM .
- 使用jmap和MAT定位内存泄漏OOM .
- 使用jmap和MAT定位内存泄漏OOM .
- JVM内存分析工具MAT使用
- 基于线上环境的jvm堆栈分析,jmap+MAT
- jmap、 jhat 分析堆内存溢出
- JVM《eclipse mat内存分析工具的使用》
- jni开发 - jmap+mat内存分析工具介绍
- java内存分析(jmap和jhat使用)
- java内存分析(jmap和jhat使用)
- 用jmap分析jvm使用状况
- 使用mat分析内存
- Jmap+MAT 排查内存泄漏
- 性能分析4~jmap命令分析:堆信息、内存溢出
- python打包.py文件为exe文件,无需安装python环境
- c++ prime plus 第三章
- 开放api接口签名验证
- Ubuntu 16.04 桌面版安装后的一些注意事项
- 仿小红书的图片标签
- 使用jmap和MAT分析JVM堆内存
- 微信支付
- JavaSE 集合框架(9)- ConcurrentHashMap
- 隐藏基于对话框的MFC应用程序窗口的方法 (推荐这个方法,非常好用)
- 浅谈web自适应
- 项目总结
- MySql sql语句
- 用IDEA基于maven项目使用mybatis-generator-plugin生成mapper和pojo
- datatabls 合并行,及在列前面添加数字