前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >JAVA NIO内存泄漏

JAVA NIO内存泄漏

作者头像
春哥大魔王
发布2018-04-16 11:06:17
1.8K0
发布2018-04-16 11:06:17
举报
文章被收录于专栏:服务端技术杂谈

前言

写NIO程序时,经常使用ByteBuffer来读取写入数据,那使用ByteBuffer.allocate()还是ByteBuffer.allocateDirect分配呢?

  • allocate()分配的是jvm堆内存,属于GC管理范畴,需要堆内拷贝,速度较慢。
  • allocateDireact()直接分配堆外内存,属于OS范畴,没有GC管理,速度较快。

我们希望使用速度更快的方式,但是没有GC管理会产生OOM的问题。

好在OS内存在java中有个DirectByteBuffer与之对应,当GC发生时,这个类会被回收,对应的OS内存会被回收,这样就满足了我们的想法。 但是如果堆内一直够用,不触发GC,DirectByteBuffer不进行GC呢?对应的OS内存也不会回收。

既然自动GC方式不靠谱,好在DirectByteBuffer里面有个Cleaner对象,里面有个clean()方法,通过这个方法我们可以通过手动方式释放了。

测试

  1. 分配-Xmx=100m,没有设置-XX:MaxDirectMemorySize,默认大小和-Xmx大小相同 //分配128MB直接内存 ByteBuffer bb = ByteBuffer.allocateDirect(10241024128);

产生OOM;

  1. 设置JVM参数-Xmx256m -XX:MaxDirectMemorySize=100M

同样的代码产生OOM;

  1. 手动释放

public static void main(String[] args) throws InterruptedException{ //分配512MB直接缓存 ByteBuffer bb = ByteBuffer.allocateDirect(10241024512);

代码语言:javascript
复制
    TimeUnit.SECONDS.sleep(10);     
    //清除直接缓存
    ((DirectBuffer)bb).cleaner().clean();
     
    TimeUnit.SECONDS.sleep(10);
     
    System.out.println("ok");
}

之后通过观察内存使用变化,发现从之前一直升高,到调用clean()之后,内存降下来,说明clean()方法生效了。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2018-04-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 春哥talk 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 测试
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档