您能否在 Java 中排除垃圾收集器跟踪的对象?

Can you exclude an object from being tracked by the garbage collector in Java?

我有一个相当独特的 Java 服务,我正在使用它有一个大约 50-100 GB 的工作集。在服务中,我有一个非常复杂的对象图。这些对象中的绝大多数在整个流程生命周期中都存在,并且永远不会被收集。

目前,老年代堆的垃圾回收时间约为 10 秒。我想知道是否有任何方法可以排除这些对象以加快我的垃圾收集性能?

我能想到的唯一方法是减少堆中 Object 的数量。您可以通过直接控制图形来实现这一点。也许给自己分配一块内存作为一个大的 int[] 和 allocate/free space 在那里。你能 post 一些代码来演示图中节点的结构吗?或许我们可以给出更具体的建议。

颠倒逻辑,将图表放在单独的 运行 数据库中。然后使用更不稳定的查询进行操作。这是否必须是图形数据库取决于(- 商业 Neo4J?)。

您可能会因为持久性而付出一些速度,如果是图形数据库,则需要快速查询语言和实现。

您可能想看看一些利用 off-heap 数据存储的缓存解决方案:

The on-heap store refers to objects that will be present in the Java heap (and also subject to GC). On the other hand, the off-heap store refers to (serialized) objects that are managed by EHCache, but stored outside the heap (and also not subject to GC). As the off-heap store continues to be managed in memory, it is slightly slower than the on-heap store, but still faster than the disk store.

垃圾收集器collects/frees堆区域中无法访问的对象。 因此,要排除垃圾收集器跟踪的对象,您应该始终拥有该对象的引用 ID(最好的情况是它采用强引用形式)

如果您只需要堆外的原始数据,那么直接字节缓冲区应该可以完成这项工作。

Serializing/deserializing on-heap objects to/from 本机内存也是许多 off-heap 存储库所做的。

但如果选择正确的收藏家,它们可能并不是真正必需的。 CMS 不会移动 tenured objects 并且可以跳过大型原始数组,因此即使非常大的堆也不会产生太多额外的 GC 成本,只要它们大部分都充满了原始数组并且如果您设法将 GC 调整为避免并发模式失败。


如果你想full-blownobjects脱离垃圾收集器的掌控,那就有jillegal.

正如其名称和文档所暗示的那样,它深入到 VM 内部并带来许多 caveats/forward 兼容性问题。

仅当您认为在鲨鱼池旁进行心脏直视手术是解决问题的最合理方法时才使用它。