字节缓冲区内存分配

ByteBuffer memory allocations

我试图了解 DirectByteBuffer 如何在 Linux 上工作,并在 strace 下为 运行 编写了以下非常简单的程序:

public static void main(String[] args){
    while(true){
        ByteBuffer buffer = ByteBuffer.allocateDirect(8192);
    }
}

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

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

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

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

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

在 Oracle/OpenJDK 中,ByteBuffer.allocateDirect(n) 在 Linux 上使用 Unsafe.allocateMemory(n) which in turn calls malloc

在 Linux 上,malloc 从内存池中为较小的分配(例如 8KB)进行分配,但是,对于 128KB 或更大的分配,它会添加一个新的 mmap

I expected actually some mmap or sys_brk syscalls to allocate memory from the operating system directly

尝试一次分配 128 << 10 或 128 KB。

This seems the reason that allocating direct buffer is slower than allocating heap buffer since it requires syscall for each allocation.

系统调用增加了大约 2 微秒。并不打算经常分配和释放直接的 ByteBuffer。您应该找到重用这些缓冲区的方法。

Please correct me if I'm wrong, but heap buffer allocation (if happens inside TLAB) is equivalent to returning a pointer to pre-allocated heap memory.

正确。本机内存中的较小分配使用本机堆。

QUESTION: Why can't we do the same for direct memory?

确实如此。

Return a pointer to pre-allocated memory?

它不会为 128 KB+ 执行此操作以将内存释放回 OS。