内存映射文件和内存映射文件Java 对象的透明持久化
大家好,
我想通过内存映射文件实现Java对象的透明持久化(利用操作系统分页/交换机制)。
我的问题是:如何将 Java 对象移动到我的内存映射块? 另外,我怎样才能强制一个新的对象实例驻留在这样的块中?
众所周知,内存映射块可以看作是一个字节数组,而我在这里真正要问的是如何重叠Java 对象的地址空间与此类数组之一?这样我们仍然可以通过对象操作数据,同时操作系统透明地处理持久性(写入脏页)。
如果Java不允许我这样做,那么跨平台和跨平台是什么?你会建议我使用垃圾收集的面向对象语言吗?
预先感谢大家。
Greeting All,
I want to achieve transparent persistence of Java objects through memory-mapped files (utilize the OS paging/swapping mechanism).
My problem is: how can I move a Java object to my memory-mapped block ?
Plus, how can I force a new object instance to reside in such blocks ?
As you all know, a memory-mapped block can be seen as a byte array, and what I am really asking here is how to overlap the address space of Java objects with the one of such arrays ? So that we can still manipulate the data via objects while OS handles persistence transparently (writes dirty pages).
If Java does not allow me for this, what cross-platform & garbage-collecting OO language would you advise me to use ?
Thank you all in advance.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
实现此目的的唯一方法是使用您自己的 Java VM 并添加此功能。当然,您编写的代码不是用 Java 编写的,而是用实现 VM 的语言编写的。很久以前,Gemstone 在其对象数据库引擎中使用了这种方法。
今天的对象数据库(我正在开发一个)并不以这种方式做事。增强字节码以跟踪字段访问并使用反射或注入方法将对象转换为某种序列化形式要简单得多。这表现相当不错。如果您想支持查询,则无论如何都必须使用各个字段值来对其进行索引。
对于我们来说,为我们想要运行的所有平台维护一个虚拟机是不可能的。我们也不可能说服认真的客户将他们的整个(银行)应用程序依赖于我们定制的虚拟机。
如果您对生成基于 Java VM 的解决方案非常感兴趣:
曾经有一个有趣的Java研究项目,用于正交透明持久性,称为“Forest”。您也许能够找到旧论文甚至源代码。
如果您正在寻找一种不同的语言来直接从内存中获取“对象”:C++ 可以让您做到这一点。有一些用 C++ 编写的旧对象数据库使用这种方法。
...但是,嘿,这太疯狂了,使用页面错误来加载对象。这些对象数据库产生了不好的形象。我希望我们很快就能扭转局面。
The only way you can do this is by using your own Java VM and adding this functionality. Of course the code that you would write would not be in Java but in the language the VM is implemented in. Quite some time ago Gemstone used this approach for their object database engine.
Todays object databases (I work on one.) don't do things this way. It's much more straightforward to enhance bytecode to track field access and to use reflection or injected methods to turn objects into some kind of serialized form. This performs quite good. If you want to support querying, you have to work with individual field values anyway to index them.
For us it would just not be doable to maintain a VM for all the platforms that we want to run on. We also couldn't possibly convince serious customers to rely their entire (banking) application on a VM that we customize.
If you are seriously interested in producing a solution based on a Java VM:
There used to be an interesting Java research project for orthogonal transparent persistence called "Forest". You may be able to find old papers or even source code.
If you are looking for a different language to take "objects" from memory directly: C++ will let you do that. There are some old object databases written in C++ that use this approach.
...but hey, that's crazy stuff, using page faults to load objects. These kind of object databases produced the bad image. I hope we will turn it around again soon.
据我所知这是不可能的。运行时不允许这样做有几个充分的理由。
由于所有这些原因,您无法内存映射 Java/.NET 对象。支持这样的功能将使 JVM/CLR 变得极其复杂。
JVM/CLR 仍然允许您以类似数组的抽象形式访问内存映射文件,您可以在其中写入/读取字节。除此之外,您可以实现您的持久性机制。从简单的序列化到复杂的数据库。
有些对象数据库非常接近提供透明的持久性。那么对象的行为就像持久数据结构/内存映射对象。
This is afaik not possible. And there are several good reasons why the runtime doesn't allow this.
For all these reasons you cannot memory-map Java/.NET-objects. Supporting such a feature would make the JVM/CLR extremely complex.
The JVM/CLR still give you access to Memory-Mapped files as an array-like abstraction, where you can write/read bytes. On top of this you can implement your persistence-mechanism. From simple serialisation to complex databases.
There are object-databases which come quite close to provide transparent persistence. Then objects behave like persistent datastructures / memory-mapped objects.
你不能。
Java 在设计上强制执行类型安全和引用完整性。也就是说,如果我有一个引用类型 T 的字段,我知道它指向 T 的一个实例。(除非类型擦除引入堆污染)。这与 C++ 等“不安全”语言形成鲜明对比,在 C++ 中,引用很可能指向无效位置,而该引用可能会导致“内存损坏”。
如果 Java 允许将 byte[] 视为
Object
,则它无法保证这种引用完整性。You can't.
Java, by design, enforces type safety and referential integrity. That is, if I have a field of reference type T, I know it points to a instance of T. (Barring heap-pollution introduced by type erasure). This is in contrast to "unsafe" languages such a C++ where it is quite possible for a reference to point to an invalid location, where that reference can cause "memory corruption".
If Java allowed to treat a byte[] as
Object
, it could not guarantee such referential integrity.