`
flychao88
  • 浏览: 743586 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

NIO DirectByteBuffer 内存泄露的测试

 
阅读更多

    写NIO程序经常使用ByteBuffer来读取或者写入数据,那么使用ByteBuffer.allocate(capability)还是使用ByteBuffer.allocteDirect(capability)来分配缓存了?第一种方式是分配JVM堆内存,属于GC管辖范围,由于需要拷贝所以速度相对较慢;第二种方式是分配OS本地内存,不属于GC管辖范围,由于不需要内存拷贝所以速度相对较快。

 

    我们肯定想选择比较快的,但问题是直接内存不属于GC管辖范围,需要弄清楚这部分内存如何管理,否则造成内存泄露就麻烦了。本地内存在JAVA中有一个对应的包装类DirectByteBuffer,该类属于Java类,适当的时候会被GC回收,当它被回收前会调用本地方法把直接内存给释放了,所以本地内存可以随DirectByteBuffer对象被回收而自动回收,貌似没有问题;但如果不断分配本地内存,堆内存很少使用,那么JVM就不需要执行GC,DirectByteBuffer对象们就不会被回收,这时候堆内存充足,但本地内存可能已经使用光了,再次尝试分配本地内存就会出现OutOfMemoryError,那程序就直接崩溃了。

 

    有没有解决方案?自动释放不靠谱,我们是否可以手动释放本地内存,把握主动权?果然DirectByteBuffer持有一个Cleaner对象,该对象有一个clean()方法可用于释放本地内存,所以需要的时候我们可以调用这个方法手动释放本地内存。

 

以下代码与测试场景帮助理解与证实以上描述。

 

代码1:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package com.stevex.app.nio;
 
import java.nio.ByteBuffer;
import java.util.concurrent.TimeUnit;
 
public class DirectByteBufferTest {
    public static void main(String[] args) throws InterruptedException{
            //分配128MB直接内存
        ByteBuffer bb = ByteBuffer.allocateDirect(1024*1024*128);
         
        TimeUnit.SECONDS.sleep(10);
        System.out.println("ok");
    }
 
}

 

测试用例1:设置JVM参数-Xmx100m,运行异常,因为如果没设置-XX:MaxDirectMemorySize,则默认与-Xmx参数值相同,分配128M直接内存超出限制范围。

1
2
3
4
5
Exception in thread "main" java.lang.OutOfMemoryError: Direct buffer memory
    at java.nio.Bits.reserveMemory(Bits.java:658)
    at java.nio.DirectByteBuffer.<init>(DirectByteBuffer.java:123)
    at java.nio.ByteBuffer.allocateDirect(ByteBuffer.java:306)
    at com.stevex.app.nio.DirectByteBufferTest.main(DirectByteBufferTest.java:8)

 

测试用例2:设置JVM参数-Xmx256m,运行正常,因为128M小于256M,属于范围内分配。

1
 

 

测试用例3:设置JVM参数-Xmx256m -XX:MaxDirectMemorySize=100M,运行异常,分配的直接内存128M超过限定的100M。

1
2
3
4
5
Exception in thread "main" java.lang.OutOfMemoryError: Direct buffer memory
    at java.nio.Bits.reserveMemory(Bits.java:658)
    at java.nio.DirectByteBuffer.<init>(DirectByteBuffer.java:123)
    at java.nio.ByteBuffer.allocateDirect(ByteBuffer.java:306)
    at com.stevex.app.nio.DirectByteBufferTest.main(DirectByteBufferTest.java:8)

 

代码2:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package com.stevex.app.nio;
 
import java.nio.ByteBuffer;
import java.util.concurrent.TimeUnit;
import sun.nio.ch.DirectBuffer;
 
public class DirectByteBufferTest {
    public static void main(String[] args) throws InterruptedException{
        //分配512MB直接缓存
        ByteBuffer bb = ByteBuffer.allocateDirect(1024*1024*512);
         
        TimeUnit.SECONDS.sleep(10);
         
        //清除直接缓存
        ((DirectBuffer)bb).cleaner().clean();
         
        TimeUnit.SECONDS.sleep(10);
         
        System.out.println("ok");
    }
 
}

测试用例4:设置JVM参数-Xmx768m,运行程序观察内存使用变化,会发现clean()后内存马上下降,说明使用clean()方法能有效及时回收直接缓存。

分享到:
评论

相关推荐

    Java NIO测试示例

    Java NIO测试示例

    java nio与io性能测试

    NULL 博文链接:https://ilrxx.iteye.com/blog/1051402

    NIO服务端测试代码

    详情查看博客地址详情查看博客地址详情查看博客地址详情查看博客地址http://blog.csdn.net/g290095142/article/details/77848088

    nio测试代码

    nio测试代码,具体文章在nio的简单使用netty实战。资源好像不能免费共享,我就设置1分。

    nio2test:测试对NIO.2 AsynchronousSocketChannel的连续写入

    NIO.2插座测试仪 一个演示应用程序,用于检查是否可以使用在TCP套接字的另一端读取所有成功的写入。 建造 仅通过从命令行运行ant即可在NetBeans中构建NetBeans ant项目: ant 跑步 在dist文件夹中创建的jar文件包含...

    JavaNIO内存文件系统ParallelGit.zip

    ParallelGit 是为 Git 应用准备的高性能 Java NIO 内存文件系统。ParallelGit 是基于 JGit 构建的, 可以帮助 Java 项目快速的访问 Git 文件。ParallelGit 可以帮助你操作本地 Git仓库,允许你通过 Java 7 nio 文件...

    NIO客户端测试代码

    详情查看博客地址详情查看博客地址详情查看博客地址详情查看博客地址详情查看博客地址http://blog.csdn.net/g290095142/article/details/77848088

    JavaNIO chm帮助文档

    Java NIO系列教程(一) Java NIO 概述 Java NIO系列教程(二) Channel Java NIO系列教程(三) Buffer Java NIO系列教程(四) Scatter/Gather Java NIO系列教程(五) 通道之间的数据传输 Java NIO系列教程(六)...

    尚硅谷Java视频_NIO 视频教程

    尚硅谷_NIO_通道的数据传输与内存映射文件 ·06. 尚硅谷_NIO_分散读取与聚集写入 ·07. 尚硅谷_NIO_字符集 Charset ·08. 尚硅谷_NIO_阻塞与非阻塞 ·09. 尚硅谷_NIO_阻塞式 ·10. 尚硅谷_NIO_非阻塞式 ·11. ...

    JAVA BIO AIO NIO测试代码

    对java io总结时编写的测试代码,包括BIO,NIO,AIO的实现,Java io操作是编程人员经常使用到的,以前只是使用没有对这三种IO做系统的了解,本文将对这三种IO作详细的介绍并附有测试完整代码

    默蓝网络通信测试工具(NIOSocket工具)支持TCP/IP和HTTP通信-网络通信开发人员必备

    网络通信工具,服务端和客户端连接测试工具,可单条发送,循环发送,模拟多客户端发送,本工具可以作为网络通信工具或压力测试工具, Java NIO Socket编程,需JAVA运行环境

    Java NIO - The NIO Architecture

    自JDK-1.4开始的新I/O(NIO)为Java程序员提供了新的高效率的I/O能力。效率的提高主要来源于一个新的内存共享技术。传统上,Java内存来自JVM的堆,Native code(JNI)不能很好的与Java code共享这些Java内存,因为Native ...

    NIO 入门.chm,NIO 入门.chm

    NIO入门.chm NIO入门.chm NIO入门.chm

    Java IO NIO and NIO 2 无水印pdf

    Java IO NIO and NIO 2 英文无水印pdf pdf所有页面使用FoxitReader和PDF-XChangeViewer测试都可以打开 本资源转载自网络,如有侵权,请联系上传者或csdn删除 本资源转载自网络,如有侵权,请联系上传者或csdn...

    java NIO和java并发编程的书籍

    java NIO和java并发编程的书籍java NIO和java并发编程的书籍java NIO和java并发编程的书籍java NIO和java并发编程的书籍java NIO和java并发编程的书籍java NIO和java并发编程的书籍java NIO和java并发编程的书籍java...

    Java堆外内存泄露场景总结.pdf

    Java堆外内存泄露场景总结,包含几个常用的可能,如:JNI,NIO,AWT/Swing,Inflater&Deflater;

    nio-benchmark:Java NIO回显服务器的基准测试

    使用JMH的Java NIO回显服务器的基准测试 基准测试针对各种服务器运行相同的客户端代码。 客户 客户端主程序是nio.JMHClientMain,具有可选参数: thread = 确定初始化的客户端数(默认为1) cycle = 如果为true,...

    nio压力测试

    nio-benchmark 性能压力测试

    java nio 包读取超大数据文件

    Java nio 超大数据文件 超大数据文件Java nio 超大数据文件 超大数据文件Java nio 超大数据文件 超大数据文件Java nio 超大数据文件 超大数据文件Java nio 超大数据文件 超大数据文件Java nio 超大数据文件 超大数据...

    java nio 实现socket

    java nio 实现socketjava nio 实现socketjava nio 实现socketjava nio 实现socketjava nio 实现socket

Global site tag (gtag.js) - Google Analytics