• NIO-直接内存


    写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:

    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");
        }
     
    }
    

    代码2:

    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()方法能有效及时回收直接缓存。

  • 相关阅读:
    BOM和DOM的操作
    JS介绍
    CSS
    HTML的用法
    JSP获取json格式的数据报错 Uncaught SyntaxError: Unexpected identifier
    jquery.nicescroll.min.js滚动条插件的用法
    css鼠标滑过出现文字效果
    sublime text3安装js提示的插件
    利用after和before伪元素在文字两边写横线
    html+css居中问题
  • 原文地址:https://www.cnblogs.com/zqyanywn/p/8183618.html
Copyright © 2020-2023  润新知