gpt4 book ai didi

java - 由于缓冲区大小较小导致 MappedByteBuffer OOM?

转载 作者:太空宇宙 更新时间:2023-11-04 14:46:56 28 4
gpt4 key购买 nike

我遇到了一个问题,我创建了大小为 1KB 的 MappedByteBuffer,并滑动了大小为 20MB 的文件。

for(20MB file) {
writeBuffer = fc.map(MapMode.READ_WRITE, writeIndex, mappingSize);
// write data into the writeBuffer
//update to new write index
}

在本例中,我创建了一大堆 1KB MappedByteBuffer,我认为在文件中前进时可以重用它们,但显然这里的情况并非如此,因为我遇到了 OOM一段时间后。

但是,当我编辑映射大小并将其设置为 128KB(对于上面的相同代码)时,测试运行良好(没有 OOM)。

有人可以解释一下 MappedByteBuffer 的缓冲区大小如何影响系统分配和回收资源(本例中为内存)的方式吗?

最佳答案

看起来您点击了 max_map_count限制。它是 Linux 进程可以创建的最大映射数。 root 可以使用 sysctl -w vm.max_map_count=XXX 来更改此设置。

在 Java 中,未引用的 MappedByteBuffer 和底层文件映射在 GC 之前不会被释放。但只有当 Java 堆内存耗尽时才会触发 GC(不考虑分配的 native 内存量)。这意味着您可以创建数千个不会自动释放的未引用的 MappedByteBuffer。顺便说一句,有一个 hack 可以使用非公共(public) API 手动释放它们:

    ((sun.nio.ch.DirectBuffer) mappedByteBuffer).cleaner().clean();

此外,映射 1K 区域没有任何意义,因为操作系统文件映射始终是页对齐的,即起始地址和大小始终是 4096 字节的倍数。

附注
有一种特殊情况,Java 会强制对失败的 map() 进行 GC,以释放未引用缓冲区占用的内存。请参阅FileChannelImpl.java 。但是,如果您通过 JVM 选项禁用显式 GC,那么您就会遇到麻烦。

关于java - 由于缓冲区大小较小导致 MappedByteBuffer OOM?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24295993/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com