ByteBuffer 内存分配

我试图了解DirectByteBufferLinux 上的工作原理并编写了以下非常简单的程序以在 strace 下运行:


public static void main(String[] args){

    while(true){

        ByteBuffer buffer = ByteBuffer.allocateDirect(8192);

    }

}

我期望实际上一些mmap或sys_brk系统调用直接从操作系统分配内存,但实际上它只是设置了请求页面的读写保护。我的意思是这样的:


mprotect(0x7fa9681ef000, 8192, PROT_READ|PROT_WRITE) = 0

这似乎是分配直接缓冲区比分配堆缓冲区慢的原因,因为每次分配都需要系统调用。


如果我错了,请纠正我,但堆缓冲区分配(如果发生在 TLAB 内)相当于返回一个指向预分配堆内存的指针。


问题:为什么我们不能对直接内存做同样的事情?返回一个指向预分配内存的指针?


沧海一幻觉
浏览 193回答 1
1回答

RISEBY

在 Oracle/OpenJDK 中,ByteBuffer.allocateDirect(n)使用Unsafe.allocateMemory(n)在 Linux 上调用malloc。在 Linux 上,malloc 从内存池中分配较小的分配,例如 8KB,但是,对于 128 KB 或更多的分配,它会添加一个新的mmap.我实际上期望一些 mmap 或 sys_brk 系统调用直接从操作系统分配内存尝试一次分配128 << 10或 128 KB。这似乎是分配直接缓冲区比分配堆缓冲区慢的原因,因为每次分配都需要系统调用。系统调用增加了大约 2 微秒。不打算经常分配和释放直接的 ByteBuffer。您应该找到重用这些缓冲区的方法。如果我错了,请纠正我,但堆缓冲区分配(如果发生在 TLAB 内)相当于返回一个指向预分配堆内存的指针。正确的。本机内存中较小的分配使用本机堆。问题:为什么我们不能对直接内存做同样的事情?确实如此。返回一个指向预分配内存的指针?它不会为 128 KB+ 执行此操作以将内存释放回操作系统。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java