Java map / nio / NFS 问题导致虚拟机故障:“编译的 Java 代码中最近的不安全内存访问操作发生故障”

2024-01-02

我已经为特定的二进制格式编写了一个解析器类(nfdump http://nfdump.sf.net/如果有人感兴趣)它使用 java.nio映射字节缓冲区 http://java.sun.com/j2se/1.4.2/docs/api/java/nio/MappedByteBuffer.html读取每个几 GB 的文件。二进制格式只是一系列标头和大部分固定大小的二进制记录,通过调用 nextRecord() 将其提供给被调用者,该状态机会推送状态机,完成后返回 null。它表现良好。它可以在开发机器上运行。

在我的生产主机上,它可以运行几分钟或几个小时,但似乎总是抛出“java.lang.InternalError:编译的 Java 代码中最近不安全的内存访问操作中发生故障”,指着 Map.getInt 之一、getShort方法,即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* 方法来读取短整型、整数、长整型和其他字节序列,然后到达文件末尾并关闭映射。

我从未见过我的开发主机上抛出异常。但我的生产主机和开发主机之间的显着区别在于,在前者上,我通过 NFS 读取这些文件的序列(最终可能为 6-8TB,仍在增长)。在我的开发计算机上,我在本地选择了较小的这些文件 (60GB),但当它在生产主机上崩溃时,通常会在它达到 60GB 数据之前就发生。

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

我认为,如果我的代码中存在错误,那么 JVM 中的错误就足够多,不会引发适当的异常!但我认为这只是由于 NFS 和 mmap 之间的交互而导致的一个特定的 JVM 实现错误,可能是重复出现的6244515 https://bugs.java.com/bugdatabase/view_bug?bug_id=6244515这是官方固定的。

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

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


我会重写它而不使用mapped蔚来。如果您正在处理多个文件,则会出现一个问题,即映射的内存永远不会被释放,因此您将耗尽虚拟内存:注意,这不一定只是与垃圾收集器交互的 OutOfMemoryError,它可能是一个无法分配新的映射缓冲区。我会使用 FileChannel。

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java map / nio / NFS 问题导致虚拟机故障:“编译的 Java 代码中最近的不安全内存访问操作发生故障” 的相关文章

  • 如何使用 Java 和 Selenium WebDriver 在 C 目录中创建文件夹并需要将屏幕截图保存在该目录中?

    目前正在与硒网络驱动程序和代码Java 我有一种情况 我需要在 C 目录中创建一个文件夹 并在该文件夹中创建我通过 selenium Web 驱动程序代码拍摄的屏幕截图 它需要存储在带有时间戳的文件夹中 如果我每天按计划运行脚本 所有屏幕截
  • 为什么 i++ 不是原子的?

    Why is i Java 中不是原子的 为了更深入地了解 Java 我尝试计算线程中循环的执行频率 所以我用了一个 private static int total 0 在主课中 我有两个线程 主题 1 打印System out prin
  • 如何在 Play java 中创建数据库线程池并使用该池进行数据库查询

    我目前正在使用 play java 并使用默认线程池进行数据库查询 但了解使用数据库线程池进行数据库查询可以使我的系统更加高效 目前我的代码是 import play libs Akka import scala concurrent Ex
  • Java - 将节点添加到列表的末尾?

    这是我所拥有的 public class Node Object data Node next Node Object data Node next this data data this next next public Object g
  • Java JDBC:更改表

    我希望对此表进行以下修改 添加 状态列 varchar 20 日期列 时间戳 我不确定该怎么做 String createTable Create table aircraft aircraftNumber int airLineCompa
  • 如何找到给定字符串的最长重复子串

    我是java新手 我被分配寻找字符串的最长子字符串 我在网上研究 似乎解决这个问题的好方法是实现后缀树 请告诉我如何做到这一点或者您是否有任何其他解决方案 请记住 这应该是在 Java 知识水平较低的情况下完成的 提前致谢 附 测试仪字符串
  • Final字段的线程安全

    假设我有一个 JavaBeanUser这是从另一个线程更新的 如下所示 public class A private final User user public A User user this user user public void
  • 列出jshell中所有活动的方法

    是否有任何命令可以打印当前 jshell 会话中所有新创建的方法 类似的东西 list但仅适用于方法 您正在寻找命令 methods all 它会打印所有方法 包括启动 JShell 时添加的方法 以及失败 被覆盖或删除的方法 对于您声明的
  • Liferay ClassNotFoundException:DLFileEntryImpl

    在我的 6 1 0 Portal 实例上 带有使用 ServiceBuilder 和 DL Api 的 6 1 0 SDK Portlet 这一行 DynamicQuery query DynamicQueryFactoryUtil for
  • 磁模拟

    假设我在 n m 像素的 2D 表面上有 p 个节点 我希望这些节点相互吸引 使得它们相距越远吸引力就越强 但是 如果两个节点之间的距离 比如 d A B 小于某个阈值 比如 k 那么它们就会开始排斥 谁能让我开始编写一些关于如何随时间更新
  • Mockito when().thenReturn 不必要地调用该方法

    我正在研究继承的代码 我编写了一个应该捕获 NullPointerException 的测试 因为它试图从 null 对象调用方法 Test expected NullPointerException class public void c
  • 总是使用 Final?

    我读过 将某些东西做成最终的 然后在循环中使用它会带来更好的性能 但这对一切都有好处吗 我有很多地方没有循环 但我将 Final 添加到局部变量中 它会使速度变慢还是仍然很好 还有一些地方我有一个全局变量final 例如android Pa
  • 加密 JBoss 配置中的敏感信息

    JBoss 中的标准数据源配置要求数据库用户的用户名和密码位于 xxx ds xml 文件中 如果我将数据源定义为 c3p0 mbean 我会遇到同样的问题 是否有标准方法来加密用户和密码 保存密钥的好地方是什么 这当然也与 tomcat
  • Java执行器服务线程池[关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 如果我使用 Executor 框架在
  • 如何从终端运行处理应用程序

    我目前正在使用加工 http processing org对于一个小项目 但是我不喜欢它附带的文本编辑器 我使用 vim 编写所有代码 我找到了 pde 文件的位置 并且我一直在从 vim 中编辑它们 然后重新打开它们并运行它们 重新加载脚
  • 如何从指定日期获取上周五的日期? [复制]

    这个问题在这里已经有答案了 如何找出上一个 上一个 星期五 或指定日期的任何其他日期的日期 public getDateOnDay Date date String dayName 我不会给出答案 先自己尝试一下 但是 也许这些提示可以帮助
  • 在mockito中使用when进行模拟ContextLoader.getCurrentWebApplicationContext()调用。我该怎么做?

    我试图在使用 mockito 时模拟 ContextLoader getCurrentWebApplicationContext 调用 但它无法模拟 here is my source code Mock org springframewo
  • simpleframework,将空元素反序列化为空字符串而不是 null

    我使用简单框架 http simple sourceforge net http simple sourceforge net 在一个项目中满足我的序列化 反序列化需求 但在处理空 空字符串值时它不能按预期工作 好吧 至少不是我所期望的 如
  • 在 Maven 依赖项中指定 jar 和 test-jar 类型

    我有一个名为 commons 的项目 其中包含运行时和测试的常见内容 在主项目中 我添加了公共资源的依赖项
  • java.lang.IllegalStateException:驱动程序可执行文件的路径必须由 webdriver.chrome.driver 系统属性设置 - Similiar 不回答

    尝试学习 Selenium 我打开了类似的问题 但似乎没有任何帮助 我的代码 package seleniumPractice import org openqa selenium WebDriver import org openqa s

随机推荐