2

我试图弄清楚是否有一种“简单”的方法可以在 JVM 内存中持久存储一个大对象实例,以便其他程序可以共享和重复使用它。我正在使用 java 8 处理 netbeans。数据是大约 500 MB 的序列化对象。它们很容易放入 RAM,但每次从磁盘反序列化都需要几分钟。

目前,该程序在每次运行时将一个序列化对象从本地磁盘加载到内存中。由于仅在测试期间读取数据,因此最好将其保存在内存中并在每次运行时直接访问它。

我们已经研究过 RMI,但开销、编组过程和传输会影响性能。我想知道是否有更直接的方法可以从运行在同一 JVM 上的程序访问数据,例如共享内存。

多次运行是为了在相同的输入数据上测试不同的处理/参数。

我愿意就实现这种“预加载”的最佳实践提出建议,任何提示将不胜感激。

谢谢

4

2 回答 2

1

Java 序列化永远不会作为一种持久性机制发挥出色 - 对类的更改很容易与先前存储的对象不兼容,这意味着它们不能再被反序列化(并且通常所有对象模型都会以一种或另一种方式发展)。

虽然建议在 SO 上确实是题外话,但我建议您考虑使用分布式缓存,例如HazelcastCoherence

虽然您仍然需要加载对象,但HazelcastCoherence都提供了一种可扩展的方式来存储可以从其他 JVM 访问的对象,并提供各种方式来处理长期持久性和不断发展的类。

但是,两者都不适用于大对象图,因此您应该考虑将模型分解为键/值对。

一个例子可能是一个订单系统,其中键可能是这样的组合:

public class OrderItemKey
{
  private OrderKey orderKey;
  private int itemIdex;

  ...
} 

像这样的价值:

public class OrderItem
{
  private ProductKey productKey;
  private int quantity;

  ...
}

其中OrderItems 可能在一个缓存中,而Products 可能在另一个缓存中。

一旦你有了一个可以很好地使用分布式缓存的模型,你就需要查看相关对象的协同定位(因此它们存储在同一个 JVM 中)和复制引用对象。

当您对模型感到满意时,请考虑将处理移动到对象所在的缓存节点中,而不是将它们拉出以对它们执行操作。这减少了网络负载,带来了可观的性能提升。

于 2015-09-08T08:22:06.097 回答
0

如果我理解得很好,您需要从磁盘读取大量数据并将这些数据仅用于测试目的。

因此,每次运行测试时都需要重新加载它们,这会减慢测试速度。

如果是这种情况,您还可以尝试在内存(ram 磁盘)上创建磁盘。因此,您的文件将保存在具有 ram 性能的磁盘上。

这是命令 ramfs 在 linux 系统上创建它的链接

于 2015-09-08T08:22:47.163 回答