java.util.zip.Deflater使用不当引发jvm crash及问题排查

最近使用第三方开源库jflvlib录制flv格式视频,测试过程发现,视频录制进程经常挂掉;
java启动参数中已经配置内存溢出时导出日志文件-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/export/Logs/xxx.dump和jvm crash的日志输出路径-XX:ErrorFile=/export/Logs/xxx.log,但是进程挂掉后没有找到任何日志输出;

1. 启动视频录制,使用top命令查看进程cpu、内存消耗情况,内存暂用:83.1%≈1.5G

2. 使用jvisualvm查看Heap、PermGen内存暂用正常,heap使用:≈50M

由于两种方式看到的内存相差很大;只有一种可能代码中使用了直接内存(Direct Memory),
下载直接内存查看工具google-perftools:http://code.google.com/p/google-perftools/downloads/list

3. 使用perftools查看java.util.zip.Deflater占用绝大多数,代码中有使用开源项目jflvlib来生成视频,其中有一段使用java.util.zip.Deflater的视频压缩代码

参考网上ibm一篇文章:http://www-01.ibm.com/support/docview.wss?uid=swg21227106,deflater必须要调用end方法,不然可能导致oom或者jvm crash。
If a deflater object is not explicitly closed and ended, a native memory leak occurs. This leak can result in OutOfMemoryError’s and/or Java™ Virtual Machine (JVM) crashes.
修改后代码如下:

4. 根据配置jvm崩溃会有错误日志,jvm内存溢出也有会有二进制日志文件;由于崩溃现场没任何日志,一种可能操作系统直接干掉了该进程。
linux oom_killer是一种自我保护机制,当系统分配不出内存时(触发条件)会触发这个机制
查询操作系统日志:egrep -i ‘killed process’ /var/log/messages  确实进程被操作系统干掉了

Tagged:

Comments are closed.