为了账号安全,请及时绑定邮箱和手机立即绑定

ByteBuffer 内存分配

ByteBuffer 内存分配

沧海一幻觉 2021-10-28 17:18:39
我试图了解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 内)相当于返回一个指向预分配堆内存的指针。问题:为什么我们不能对直接内存做同样的事情?返回一个指向预分配内存的指针?
查看完整描述

1 回答

?
RISEBY

TA贡献1856条经验 获得超5个赞

在 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+ 执行此操作以将内存释放回操作系统。


查看完整回答
反对 回复 2021-10-28
  • 1 回答
  • 0 关注
  • 188 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信