【问题标题】:Allocating memory outside JVM and using it inside JVM在 JVM 外部分配内存并在 JVM 内部使用它
【发布时间】:2016-02-06 13:43:20
【问题描述】:

是否可以在 JVM 内存之外创建一个持久内存对象,可以在 JVM 内部作为对象使用,以便在 JVM 重启后仍然存在?

特别的想法是,我们可以在 JVM 之外分配内存,然后使用 JNI 接口来访问该内存并关联一些 Java 数组。

有人尝试过这种黑客行为吗?任何平台依赖都足够了。

例如,这有助于在 JVM 进程重新启动期间执行内存中 DB 加载的优化。

【问题讨论】:

  • 您肯定无法将它分配给真正的 java 数组,例如 float[] 左右。但是您可以在 java 中使用外部分配的内存,方法是将它作为直接的 ByteBuffer 返回,它是通过 JNI 使用 NewDirectByteBuffer 创建的。我不确定如何完成 JVM 重启的生存(目前无法明智地尝试一下),但是 如果 这部分可以解决,直接ByteBuffer 可能是要走的路。

标签: java memory jvm


【解决方案1】:

是的,这是完全可能的,即使没有 JNI。

我们的想法是让MappedByteBuffertmpfs 文件系统上的“文件”支持。例如。在 Linux 上,您可以为此使用 /dev/shm(或 /run/shm)挂载点。

这种 MappedByteBuffer 的性能将与其他 Direct ByteBuffer 相同,但它会持续 JVM 重启,即您可以在新的 JVM 中再次映射这个“文件”。 (我用引号写“文件”,因为它看起来像应用程序的常规文件,但它实际上是驻留在 RAM 中的共享内存区域)。我们积极地将这种技术用于我们的生产内存缓存。

【讨论】:

  • 问题中没有提到 Linux ......所以这是特定于平台的 - 或者在 Windows 上是否有类似的东西?
  • @Marco13 在 windows 上你可以使用 ramdisk 但我认为你必须安装它。
【解决方案2】:

您可以自己使用 MappedByteBuffer,也可以使用构建在 MappedByteBuffer 之上的数据结构,以便在重新启动时可用,甚至在 JVM 之间共享。

Chronicle-Map 有一个建模为 ConcurrentMap 的键值对存储。例如Map<String, YourType>

Chronicle-Queue 是系统中每个事件的日志,例如您可以实时使用的日志。

这些都是开源和免费的,让您不必弄清楚如何从持久存储中存储和检索对象。

注意:由于这些是堆外和持久化的,因此它们的大小可以达到 TB,而不会影响 GC 暂停时间。

【讨论】:

    猜你喜欢
    • 2013-07-27
    • 2016-06-01
    • 2010-10-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多