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
分享到:
相关推荐
DirectByteBuffer是Java NIO(New Input/Output)库中的一个重要组成部分,它提供了对系统内存的直接访问,从而在处理大量数据时能显著提高性能。在Java编程中,尤其是在服务器端和高并发环境下,理解并使用...
《DirectByteBuffer2》是Java基础课程中的一个重要章节,主要探讨了Java内存管理中直接缓冲区的概念、使用及其优势。在Java编程中,内存管理对于性能优化至关重要,而直接缓冲区(Direct ByteBuffer)作为Java NIO...
DirectByteBuffer HeapByteBuffer ShortBuffer IntBuffer LongBuffer FloatBuffer DoubleBuffer CharBuffer Selector选择器 Selector的作用就是配合一个线程来管理多个channel,获取这些channel上发生
`DirectByteBuffer`是一个Java类,它本身存储在堆内存中,但是通过`native`方法`unsafe.allocateMemory(size)`来分配和管理堆外内存。这里的`native`方法是C语言实现的,利用了操作系统级别的内存分配,使得数据可以...
因此,合理控制堆外内存的使用量,监控DirectByteBuffer的分配和释放,以及理解JVM如何管理这部分内存,都是Java开发者必备的知识。 在实际开发中,可以通过调整JVM参数,如`-XX:MaxDirectMemorySize`来限制堆外...
异常现象主要表现为:在尝试清理内存映射文件时,由于Java反射机制调用了`java.nio.DirectByteBuffer`类中的`viewedBuffer()`方法,导致`NoSuchMethodException`异常。异常堆栈跟踪显示,问题出在`MapedFile`类的...
6. **堆外内存访问**:通过DirectByteBuffer,可以直接在Java代码中访问操作系统分配的堆外内存,提高了处理大块数据的性能。 7. **改进的类型推断**:编译器能够更智能地推断泛型方法的类型参数。 **64位版本的...
`DirectByteBuffer`是`ByteBuffer`的一个实现,它与`Non-Direct Buffer`(即堆缓冲区)有所不同。直接缓冲区在Java中使用JNI(Java Native Interface)直接在物理内存中分配,而不需要经过Java堆,这通常能提高性能...
* 使用堆外内存,例如使用 DirectByteBuffer 等。 栈溢出是指函数调用栈空间不足,导致函数调用无法继续执行的错误。常见的栈溢出情况有: 1. 局部数组过大:当函数内部的数组过大时,有可能导致堆栈溢出。 2. ...
例如,通过使用DirectByteBuffer和FileRegion,可以减少从磁盘到网络的数据复制步骤。 3. **Channel与Handler**:Netty 的I/O操作基于Channel(通道)和EventLoop(事件循环)的概念。Channel是连接到某个网络端点...
NIO是一种基于通道和缓冲区的I/O方式,它可以使用Native函数库直接分配堆外内存(区别于JVM的运行时数据区),然后通过一个存储在java堆里面的DirectByteBuffer对象作为这块内存的直接引用进行操作。这样能在一些...
DirectByteBuffer是直接分配于系统内存的Buffer,减少了一次从内核空间到用户空间的复制,适用于大型、持久的缓冲区。HeapByteBuffer则是由JVM管理的Buffer,适用于数据量小的场景。 - Channel(通道)与Buffer不同...
- **零拷贝(Zero-Copy)**:通过DirectByteBuffer避免了操作系统在用户态和内核态之间的数据拷贝,提高了效率。 - **ByteBuf**:Netty自定义的缓冲区,提供了比Java NIO Buffer更高效和方便的API。 - **Event...
DirectByteBuffer允许直接在Java堆外分配内存,减少了Java对象创建的开销,提高了内存访问速度,特别适用于大数据量的I/O操作。在本项目中,如果涉及到大量数据传输,例如库存统计,Java Direct可能会提高性能,降低...
在Netty中,ChannelBufferFactory可以用来创建DirectByteBuffer,而使用完后必须通过ReferenceCounted接口的release方法进行释放。如果忘记释放或者释放不当,就会造成内存泄露。 此外,监控工具如JProfiler或...
- **DirectByteBuffer 和 HeapBuffer**:DirectByteBuffer 位于堆外内存,减少系统拷贝,适用于大数据量;HeapBuffer 由 JVM 管理,适用于小数据量。 4. **Netty 的 Channel**: - **FileChannel**:读写文件的 ...
- **DirectByteBuffer**:数据存储在非JVM堆上,适用于大数据量传输,能有效减少数据复制带来的开销。 - **理解关键概念**:Capacity(容量)、Limit(限制)、Position(位置)、Mark(标记)。例如,`0–mark–...
针对这些问题,文中提供了一些解决思路,例如针对物理内存耗光的问题,可以通过分析线程分配的堆栈情况找到问题所在,并修复无限制使用DirectByteBuffer的代码段,避免创建过多的DirectByteBuffer实例,从而缓解内存...