11、JVM 调优实战 - 实战分析解决 JVM 直接内存泄漏问题

今天解决直接内存内内泄漏问题:

1、内存泄漏问题解决

linux环境这个程序可以访问服务器的 8888 端口,这将会把内存使用的阈值增加到 85% ,我们的程序会逐渐把这部分内存占满

curl http://127.0.0.1:8888/

 

 

特意这么做也是为了方便你的观察,通过内存的增长我们可以大致知道问题的点。

2、问题关键点

GZIPInputStream 使用 Inflater 申请堆外内存、我们没有调用 close() 方法来主动释放。如果忘记关闭, Inflater 对象的生命会延续到下一次 GC ,有一点 类似堆内的弱引用。在此过程中,堆外内存会一直增长。

 

 

 

 

 

3、问题修复

调用close() 方法来主动释放,放置内存泄漏

 

 

 

4、 Top–p查看,这个内存和堆内存的情况就比较符合;

 

 

 

5、 问题得到最终得到解决;

直接内存总结

直接内存主要是通过 DirectByteBuffer 申请的内存,可以使用参数“ MaxDirectMemorySize ”来限制它的大小 其他堆外内存( 直接内存 ) ,主要是指使用了 Unsafe 或者其他 JNI 手段直接直接申请的内存。这种情况下没有任何参数能够阻挡它们,要么靠它自己去释 放一些内存,要么等待操作系统对它来处理。所以如果你对操作系统底层以及内存分配使用不熟悉,最好不要使用这块,尤其是 Unsafe 或者其他 JNI 手 段直接直接申请的内存.。那为什么要讲呢,EhCache 这种缓存框架,提供了多种策略,可以设定将数据存储在非堆上。 还有像 RocketMQ 都走了堆外分配,所以我们又必须要去了解他。