jmap -histo java内存泄漏排查 -XX:MaxDirectMemorySize=2G

最近发现有2个odm的服务器经常内存task这个java进程占用内存超过9.2个G  把服务器内存耗尽了,服务器只剩下100-200M 把服务器拖得很卡

先用 jmap -histo 7917 > 7917.txt   排查堆内存有没有内存泄漏。没有发现heap中有什么异常很大的对象,total也才3个G

后面发现可能是堆外内存native heap占用过多,这些内存占用不会体现在jmap -histo 命令输出内容中,只有用top -p 7917 看java进程占用总大小。

后面设置了java启动参数   -XX:MaxDirectMemorySize=2G   再观察一下,因为如果XX:MaxDirectMemorySize不设置就默认和xmx一样的大小6G 可能最后就把机器的内存吃完了

参考如下文章

https://blog.csdn.net/PioneerX_x/article/details/81489702

前几天写了一套java服务用于对接视频单位的sdk接口,但是项目环境测试的时候出现了问题:

         在linux环境下使用top命令查看java命令的mem比值一直在缓慢的增加,第二天出现了服务宕机的情况,生成hs_err的log                   

          测试环境的配置:阿里云ecs,总物理内存7.6g 。 java服务启动参数xmx为total的7/10

          服务器上就我这一个吃大内存的服务,只有我自己用于测试使用,按照常理来说应该够用才对。

问题排查过程:

首先确定是否是内存溢出的问题 ? 

 过程:使用java自带的一些命令,jmap ,jstack等命令以及jconsole远程监控结合gc的日志进行gc情况的排查,java堆因为内存较小              的问题  除了eden的gc频率比较快一点,其他都在正常课接受范围之内。   dump下来的内存快照用mat分析也没发现问题。

结论:不是堆内存问题!

top命令下查看到的mem总数 = 系统自身耗内存 + java heap + no heap(meta space+code cache 等)*线程数 + 虚拟机进程本身 + 虚拟机栈(线程栈)*线程数 + native heap

那么既然java heap没有发现问题,再结合服务中使用jna调用so,其中so中涉及到大量的socket与缓冲区还有视频数据的接收处理等

那么怀疑native heap的使用除了问题?

过程:首先确定下XX:MaxDirectMemorySize的默认值是多少(我没有显示的去设置maxSize,关注1.8的时候对直接内存的印象还停留在旧版本的默认64m!!!)

经过一番查阅发现 1.8版本最大可以直接内存可以使用参数-XX:MaxDirectMemorySize设置,如不设置,默认值为java heap 的max最大值,-Xmx - from区域的大小(几乎等同xmx)。native heap 达到最大值,不会触发gc,如果释放不了足够的空间,引发宕机的风险。

见源码分析L:http://hllvm.group.iteye.com/group/topic/27945

然后在结合刚才的内存分配情况,会出现的内存竞争,不宕机才怪,果然!修改完参数3/10之后,项目稳定了很多!至此问题算是圆满解决!

如果该方案还没有解决你的问题,那我推荐你使用google-perftools一款google的良心工具,在linux上下载安装完成后在项目启动前加上一些启动参数的配置,就可以经过项目一段时间运行,可以统计出来内存异常的代码块了!

有关于下载的链接还有使用方式以及结构化输出后的参数说明:

下载地址:https://github.com/gperftools/gperftools

如果操作系统64位还需要先安装 libunwind库:http://download.savannah.gnu.org/releases

使用方式和参数详解:https://blog.csdn.net/turkeyzhou/article/details/8794188

如有问题探讨,可留言,看到及时回复!

原文地址:https://www.cnblogs.com/xiaohanlin/p/12803008.html