DirectByteBuffer特性说明
Java 2 SE 6 doc :
Given a direct byte buffer, the Java virtual machine will
make a best effort to perform native I/O operations directly upon it.
That is, it will attempt to avoid copying the buffer’s content to (or
from) an intermediate buffer before (or after) each invocation of one of
the underlying operating system’s native I/O operations.
- DirectBuffer通过免去中间交换的内存拷贝, 提升IO处理速度;也就是常说的zero-copy
Java 2 SE 6 doc :
The contents of direct buffers may reside outside of the
normal garbage-collected heap, and so their impact upon the memory
footprint of an application might not be obvious.
- DirectBuffer在-XX:MaxDirectMemorySize=xxM大小限制下[1], 使用Heap之外的内存, GC对此”无能为力”[2] ,也就意味着规避了在高负载下频繁的GC过程对应用线程的中断影响.
-
如果系统没有指定-XX:MaxDirectMemorySize,默认通-Xmx大小
-
//directMemory ,默认64M
String s = (String) properties.remove("sun.nio.MaxDirectMemorySize");
if (s != null) if (s.equals("-1")) {
directMemory = Runtime.getRuntime().maxMemory();
} else {
long l = Long.parseLong(s);
if (l > -1L) directMemory = l;
}
DirectByteBuffer如何内存回收
实现了一个Cleaner
cleaner = Cleaner.create(this, new Deallocator(base, size, cap));
Deallocator,实现内存回收
if (address == 0) {
// Paranoia
return;
}
unsafe.freeMemory(address);
address = 0;
Bits.unreserveMemory(size, capacity);
}
在什么时候被调用?
看看Reference里的奥秘,它内部有一个Thread ReferenceHandler,它的run 方法会调用Cleaner.clean
//截取部分代码
Reference r;
synchronized (lock) {
if (pending != null) {
r = pending;
Reference rn = r.next;
pending = (rn == r) ? null : rn;
r.next = r;
} else {
try {
lock.wait();
} catch (InterruptedException x) { }
continue;
}
}
// Fast path for cleaners
if (r instanceof Cleaner) {
((Cleaner)r).clean();
continue;
}
DirectByteBuffer如何实现zero-copy
sun.nio.ch.IOUtil
static int read(FileDescriptor filedescriptor, ByteBuffer bytebuffer, long l, NativeDispatcher nativedispatcher, Object obj)
throws IOException
{
ByteBuffer bytebuffer1;
if(bytebuffer.isReadOnly())
throw new IllegalArgumentException("Read-only buffer");
if(bytebuffer instanceof DirectBuffer)
return readIntoNativeBuffer(filedescriptor, bytebuffer, l, nativedispatcher, obj);
bytebuffer1 = null;
int j;
bytebuffer1 = Util.getTemporaryDirectBuffer(bytebuffer.remaining());
int i = readIntoNativeBuffer(filedescriptor, bytebuffer1, l, nativedispatcher, obj);
bytebuffer1.flip();
if(i > 0)
bytebuffer.put(bytebuffer1);
j = i;
Util.offerFirstTemporaryDirectBuffer(bytebuffer1);
return j;
Exception exception;
exception;
Util.offerFirstTemporaryDirectBuffer(bytebuffer1);
throw exception;
}
NativeDispatcher的实现类SocketDispatcher的read方法是native
static native int read0(FileDescriptor filedescriptor, long l, int i) throws IOException;
DirectByteBuffer用在什么地方
- jetty用来处理和socket通信使用了DirectByteBuffer
附录:
-XX:MaxDirectMemorySize
This option specifies the maximum total size of java.nio (New I/O package) direct buffer allocations.
Format
-XX:MaxDirectMemorySize=size[g|G|m|M|k|K]
Example
java -XX:MaxDirectMemorySize=2g myApp
Default Value
The default value is zero, which means the maximum direct memory is unbounded.
参考:http://www.tbdata.org/archives/801
分享到:
相关推荐
【IT十八掌徐培成】Java基础第26天-07.DirectByteBuffer.zip
【IT十八掌徐培成】Java基础第26天-08.DirectByteBuffer2.zip
NIO是一种基于通道和缓冲区的I/O方式,它可以使用Native函数库直接分配堆外内存(区别于JVM的运行时数据区),然后通过一个存储在java堆里面的DirectByteBuffer对象作为这块内存的直接引用进行操作。这样能在一些...
在JDK1.4 中新加入了NIO(New Input/Output)类,引入了一种基于通道(Channel)与缓冲区(Buffer)的I/O 方式,它可以使用native 函数库直接分配堆外内存,然后通过一个存储在Java堆中的DirectByteBuffer 对象作为这块...
使用 strace 命令来监控内存分配,找出OOM的原因 由于使用 Netty 导致的,那错误日志里可能会出现 OutOfDirectMemoryError 错误 如果直接是 DirectByteBuffer,那会报 OutOfMemoryError Direct buffer memory
Java-NIO-Programming-Cookbook英文版和配套源代码。有一个使用DirectByteBuffer和Non-Direct Buffer文件读取速度的对比实验程序和测试结果。
Java NIO通道:通道基础、文件通道、Socket通道、工具类 Java NIO缓冲区:基础、缓冲区(Buffer)、创建缓冲区、直接缓冲区(DirectByteBuffer) Java NIO选择器:核心概念、选择器使用、Demo、选择器深入、
DirectByteBuffer HeapByteBuffer ShortBuffer IntBuffer LongBuffer FloatBuffer DoubleBuffer CharBuffer Selector选择器 Selector的作用就是配合一个线程来管理多个channel,获取这些channel上发生