繁体   English   中英

内存映射文件和Java对象的透明持久性

[英]Memory-Mapped Files & Transparent Persistence of Java Objects

全都问候,

我想通过内存映射文件实现Java对象的透明持久性(利用OS分页/交换机制)。

我的问题是:如何将Java对象移动到我的内存映射块? 另外,如何强制新对象实例驻留在这些块中?

众所周知,内存映射块可以看作是一个字节数组,我在这里要问的是如何将Java对象的地址空间与这样的数组重叠? 这样我们仍然可以通过对象操纵数据,而操作系统透明地处理持久性(写脏页)。

如果Java不允许我这样做,你会建议我使用什么跨平台和垃圾收集的OO语言?

谢谢大家。

这是不可能的。 运行时不允许这样做有几个很好的理由。

  • 对象的内存布局是JVM内部的一部分。 每个JVM都可以自己决定如何布局对象。 此布局可以更改版本。 当您将对象内存映射到文件时,您将遇到麻烦。 对象布局发生变化后会发生什么? 崩溃,更新文件,做魔术? 最后,内存映射对象到文件需要指定固定的对象布局。
  • 如果添加/删除字段会发生什么? 然后对象布局肯定已经改变了。 您无法使用旧内存布局对文件进行内存映射。
  • 对象还有其他信息,例如用于虚拟函数调用的VTable,用于锁定状态的字段等。您是否还想要映射它们? 可能不是,因为那是内部运行时状态。 所以你需要总是忽略几个字节或分裂对象。 这将使内存布局极其复杂。
  • 垃圾收集器通过移动对象来压缩内存以最小化碎片。 因此,需要有一个物体的“固定”机制。 (由于互操作原因,这在.NET中是可能的)
  • 垃圾收集器几代人都在工作。 如果首先在年轻一代分配的对象。 随着它的存在,它被转移到其他一代。 内存映射对象需要异常。

由于所有这些原因,您无法对Java / .NET对象进行内存映射。 支持这样的功能会使JVM / CLR变得极其复杂。

JVM / CLR仍然允许您将内存映射文件作为类似数组的抽象访问,您可以在其中写入/读取字节。 除此之外,您还可以实现持久性机制。 从简单的序列化到复杂的数据库。 有些对象数据库非常接近,可以提供透明的持久性。 然后,对象的行为类似于持久性数据结构/内存映射对象。

您可以这样做的唯一方法是使用您自己的Java VM并添加此功能。 当然,您编写的代码不是Java,而是使用VM实现的语言。很久以前,Gemstone将这种方法用于其对象数据库引擎。

今天的对象数据库(我工作一个。)不这样做。 增强字节码以跟踪字段访问并使用反射或注入方法将对象转换为某种序列化形式更为直接。 这表现得相当不错。 如果要支持查询,则必须使用单个字段值来索引它们。

对我们来说,为我们想要运行的所有平台维护VM是不可行的。 我们也无法说服认真的客户将他们的整个(银行)应用程序放在我们定制的VM上。

如果您对生成基于Java VM的解决方案非常感兴趣:曾经有一个有趣的Java研究项目,用于称为“Forest”的正交透明持久性。 您可能能够找到旧论文甚至源代码。

如果您正在寻找另一种语言直接从内存中获取“对象”:C ++将允许您这样做。 有一些用C ++编写的旧对象数据库使用这种方法。 ...但是,嘿,这是疯狂的东西,使用页面错误来加载对象。 这些对象数据库产生了坏图像。 我希望我们能很快再次扭转局面。

你不能。

Java在设计上强制实施类型安全和参照完整性。 也就是说,如果我有一个引用类型为T的字段,我知道它指向一个T的实例(禁止由类型擦除引入的堆污染)。 这与诸如C ++的“不安全”语言形成对比,其中引用很可能指向无效位置,其中该引用可能导致“内存损坏”。

如果Java允许将byte []视为Object ,则无法保证这种引用完整性。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM