java nio 内存过大 限制_JAVA NIO内存泄漏

前言

写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()方法,通过这个方法我们可以通过手动方式释放了。

测试

分配-Xmx=100m,没有设置-XX:MaxDirectMemorySize,默认大小和-Xmx大小相同

//分配128MB直接内存 ByteBuffer bb = ByteBuffer.allocateDirect(10241024128);

产生OOM;

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

同样的代码产生OOM;

手动释放

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

TimeUnit.SECONDS.sleep(10);

//清除直接缓存

((DirectBuffer)bb).cleaner().clean();

TimeUnit.SECONDS.sleep(10);

System.out.println("ok");

}

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值