码迷,mamicode.com
首页 > 其他好文 > 详细

DirectBuffer

时间:2016-11-22 20:12:40      阅读:205      评论:0      收藏:0      [点我收藏+]

标签:out   system   set   cep   如何   str   队列   span   queue   

1.如何分配,分配是哪里的内存

ByteBuffer.allocateDirect()来分配(ByteBuffer.allocate()分配堆内内存),分配的是非Heap(堆外)的内存,不排除操作系统可能把directBuffer交换到磁盘。

DirectBuffer 大体原理就是使用 Java Heap 之外的内存,这些内存不会被通常的 GC 回收,所以就规避了 GC 对应用线程的中断影响,同时也避免了内存拷贝的开销。

2.使用场景,使用效率考量

 当系统应用场景满足:

  • 大量原生类型数据使用
  • 频繁IO操作
  • 系统处理响应速度要求快且稳定

DirectBuffer 在-XX:MaxDirectMemorySize=xxM 大小限制下, 使用Heap之外的内存, GC对此”无能为力” ,也就意味着规避了在高负载下频繁的GC过程对应用线程的中断影响.

 

3.如何回收

DirectByteBuffer 类有一个内部的静态类 Deallocator,这个类实现了 Runnable 接口并在 run() 方法内释放了内存:

 

技术分享

 

 

那这个 Deallocator 线程是哪里调用了呢?这里就用到了 Java 的虚引用(PhantomReference),Java 虚引用允许对象被回收之前做一些清理工作。在 DirectByteBuffer 的构造方法中创建了一个 Cleaner:

cleaner = Cleaner.create(this /* 这个是 DirectByteBuffer 对象的引用 */, 
new Deallocator(address, cap) /* 清理线程 */); 

而 Cleaner 类继承了 PhantomReference 类,并且在自己的 clean() 方法中启动了清理线程,当 DirectByteBuffer 被 GC 之前 cleaner 对象会被放入一个引用队列(ReferenceQueue),JVM 会启动一个低优先级线程扫描这个队列,并且执行 Cleaner 的 clean 方法来做清理工作。

 技术分享

 

4.如何监控

通过查看Bits的maxMemory和reservedMemory属性来监控使用情况。

 

package com.jvm.study.part2;

import java.lang.reflect.Field;

public class CollectDirectMemoryInfo {

    /**
     * @VM args:-XX:MaxDirectMemorySize=10m
     */
    public static void main(String[] args) throws NoSuchFieldException, SecurityException, ClassNotFoundException, IllegalArgumentException, IllegalAccessException {
        //Class c = java.nio.Bits.class; //无法访问
        Class c = Class.forName("java.nio.Bits");
        Field maxMemory = c.getDeclaredField("maxMemory");  
        maxMemory.setAccessible(true);  
        Field reservedMemory = c.getDeclaredField("reservedMemory");  
        reservedMemory.setAccessible(true);  
        synchronized (c) {  
            Long maxMemoryValue = (Long)maxMemory.get(null);  
            Long reservedMemoryValue = (Long)reservedMemory.get(null);
            System.out.println("maxMemoryValue:"+maxMemoryValue/(1024 * 1024) + "m");
            System.out.println("reservedMemoryValue:"+reservedMemoryValue/1024 * 1024 + "m");
        }  
    }
}

结果:

maxMemoryValue:10m
reservedMemoryValue:0m

5.参考

监控使用的directBuffer大小:http://stackoverflow.com/questions/3908520/looking-up-how-much-direct-buffer-memory-is-available-to-java

《应用DirectBuffer提升系统性能》http://www.tbdata.org/archives/801

《Java 的 DirectBuffer 是什么东西?》http://www.simaliu.com/archives/274.html

DirectBuffer

标签:out   system   set   cep   如何   str   队列   span   queue   

原文地址:http://www.cnblogs.com/duanxz/p/6090442.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!