当前位置: 首页 > 知识库问答 >
问题:

字节缓冲存储器分配

梁泰
2023-03-14

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

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

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

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

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

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

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

共有1个答案

萧渝
2023-03-14

在Oracle/OpenJDK中,ByteBuffer.allocateDirect(n)使用Unsafe.allocateMemory(n),后者又在Linux调用malloc。

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

实际上,我期望一些mmap或sys\u brk syscalls直接从操作系统分配内存

尝试分配128

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

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

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

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

问:为什么我们不能对直接记忆做同样的事情?

确实如此。

返回指向预分配内存的指针?

要将内存释放回操作系统,它需要128 KB的内存。

 类似资料:
  • 有没有一种方法可以在请求处理程序中获得反应堆网络中使用的字节缓冲区分配器?类似于如何在纯Netty中执行?

  • 用这种方式将字节缓冲符转换为字符串是否正确, 我问这个问题的原因是,这看起来太简单了,而像Java这样的其他方法:将字符串转换成字节缓冲符和相关问题看起来更复杂。

  • 我们正在迁移到Spring WebFlux(带有Reactornetty)。应用程序使用HTTP协议和Spring控制器。目前,我们有一种过渡解决方案,它将入站IO缓冲区累积到合成字节buf中,而不进行复制(然后将其作为输入流进行处理)。Reactornetty为我们提供直接字节缓冲区。因此,为这些缓冲区调用是至关重要的。最初我们有代码: 在处理得到的复合缓冲液后进行释放。 但当上游发布器发出错误

  • 问题内容: 有没有一种方法可以使用BufferedReader读取ByteBuffer而不必先将其转换为String?我想读取相当大的ByteBuffer作为文本行,并且出于性能方面的考虑,我想避免将其写入磁盘。在ByteBuffer上调用toString不起作用,因为生成的String太大(它抛出java.lang.OutOfMemoryError:Java堆空间)。我本来以为API中会有一些东

  • (我不计算单词可寻址的机器,也不计算Alpha(字节可寻址但缺少字节加载/存储指令)。我指的是ISA本身支持的最窄的存储指令。) 在我的研究中,当回答现代x86硬件不能将一个字节存储到内存中吗?时,我发现Alpha AXP省略字节存储的原因是假设它们将被实现为真正的字节存储到缓存中,而不是包含字的RMW更新。(因此,它会使L1d缓存的ECC保护更加昂贵,因为它需要字节粒度而不是32位)。 我假设提

  • 我正在尝试为DMA Linux编写驱动程序,但我的驱动程序一直无法执行DMA_CONCENTER_alloc,我已经增加了CMA内存和CONCENTERY_pool。。。 我错过了什么? dmesg在物理CPU 0x0上引导Linux<br>Linux版本4.14.0-xilinx-v2018.2(oe-user@oe-host)(gcc版本7.2.0(gcc))#5 SMP抢占Sun二月17日2