在 JVM 外部分配内存并在 JVM 内部使用它

2022-09-04 19:34:47

是否可以在 JVM 内存外部创建一个持久内存对象,该对象可以在 JVM 内部用作对象,以便在 JVM 重新启动后继续存在?

特别的想法是,我们可以在JVM外部分配内存,然后使用JNI接口访问此内存并将其与某些Java数组相关联。

有人试图执行这样的黑客攻击吗?任何平台依赖性就足够了。

例如,这可以帮助在重新启动 JVM 进程期间执行内存中数据库加载的优化。


答案 1

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

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

这种MappedByteBuffer的性能将与其他直接字节缓冲器相同,但它将保留JVM重新启动,即您可以在新的JVM中再次映射此“文件”。(我在引号中写“file”,因为它看起来像应用程序的常规文件,但它实际上是驻留在RAM中的共享内存区域)。我们主动将此技术用于生产内存中缓存。


答案 2

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

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

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

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

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