gpt4 book ai didi

导致虚拟机故障的 Java 映射/nio/NFS 问题 : "a fault occurred in a recent unsafe memory access operation in compiled Java code"

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:23:56 40 4
gpt4 key购买 nike

我已经为特定的二进制格式(nfdump 如果有人感兴趣)编写了一个解析器类,它使用了 java.nio 的 MappedByteBuffer。读取每个几 GB 的文件。二进制格式只是一系列 header 和大部分固定大小的二进制记录,通过调用 nextRecord() 将其馈送到被调用方,nextRecord() 会推送状态机,完成后返回 null。它表现良好。它在开发机器上运行。

在我的生产主机上,它可以运行几分钟或几小时,但似乎总是抛出“java.lang.InternalError: a fault occurred in a recent unsafe memory access operation in compiled Java code”,指出其中一个Map.getInt、getShort方法,即map中的读操作。

设置 map 的无争议(?)代码是这样的:

    /** Set up the map from the given filename and position */
protected void open() throws IOException {
// Set up buffer, is this all the flexibility we'll need?
channel = new FileInputStream(file).getChannel();
MappedByteBuffer map1 = channel.map(FileChannel.MapMode.READ_ONLY, 0, channel.size());
map1.load(); // we want the whole thing, plus seems to reduce frequency of crashes?
map = map1;
// assumes the host writing the files is little-endian (x86), ought to be configurable
map.order(java.nio.ByteOrder.LITTLE_ENDIAN);
map.position(position);
}

然后我使用各种 map.get* 方法读取短整型、整型、长型和其他字节序列,然后到达文件末尾并关闭 map 。

我从未见过在我的开发主机上抛出的异常。但是我的生产主机和开发主机之间的重要区别在于,在前者上,我正在通过 NFS 读取这些文件的序列(最终可能为 6-8TB,仍在增长)。在我的开发机器上,我在本地选择了较小的这些文件 (60GB),但是当它在生产主机上爆炸时,通常在它达到 60GB 数据之前就已经很好了。

两台机器都运行 java 1.6.0_20-b02,尽管生产主机运行的是 Debian/lenny,开发主机是 Ubuntu/karmic。我不相信这会有什么不同。两台机器都有 16GB RAM,并使用相同的 Java 堆设置运行。

我认为,如果我的代码中存在错误,那么 JVM 中的错误就足够多了,不会向我抛出适当的异常!但我认为这只是一个特定的 JVM 实现错误,由于 NFS 和 mmap 之间的交互,可能是 6244515 的重复出现。这是官方固定的。

我已经尝试添加“加载”调用以强制 MappedByteBuffer 将其内容加载到 RAM 中——这似乎延迟了我完成的一次测试运行中的错误,但没有阻止它。也可能是巧合,这是它在坠毁前经过的最长时间!

如果您已经读到这里并且以前用 java.nio 做过这种事情,您的直觉是什么?现在我的是在没有 nio 的情况下重写它 :)

最佳答案

我会在不使用映射 NIO 的情况下重写它。如果您正在处理多个文件,则会出现映射内存永远不会释放的问题,因此您将用完虚拟内存:注意,这不一定只是与垃圾收集器交互的 OutOfMemoryError,它会是一个未能分配新的映射缓冲区。我会使用 FileChannel。

话虽如此,对 NFS 文件的大规模操作总是问题重重。您最好重新设计系统,以便每个文件都由其本地 CPU 读取。通过这种方式,您还将获得巨大的速度提升,远远超过不使用映射缓冲区所损失的 20%。

关于导致虚拟机故障的 Java 映射/nio/NFS 问题 : "a fault occurred in a recent unsafe memory access operation in compiled Java code",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2949371/

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