我有一个相当独特的Java服务,我正在研究它有一个大约50-100 GB的工作集。在服务中我有一个非常复杂的对象图。绝大多数这些对象都存在于整个流程生命周期中,永远不会被收集。
目前,旧代堆的垃圾收集时间约为10秒。我想知道是否有办法排除这些对象以加快垃圾收集的性能?
答案 0 :(得分:1)
我能想到的唯一方法是减少堆中Object
的数量。您可以通过直接控制图表来实现这一目标。也许为自己分配一大块内存作为一个大的int[]
并在那里分配/释放空间。你能发布一些代码来演示图表中节点的结构吗?也许我们可以提出更具体的建议。
答案 1 :(得分:1)
您可能需要查看一些使用off-heap数据存储的缓存解决方案:
堆上存储引用将存在于Java中的对象 堆(也受GC影响)。另一方面,堆外存储 是指由EHCache管理但存储的(序列化)对象 堆外(也不受GC影响)。作为堆外商店 继续在内存中管理,它稍微慢一些 堆上存储,但仍然比磁盘存储更快。
答案 2 :(得分:1)
如果您只想在堆外部使用原始数据,那么直接字节缓冲区就可以完成这项任务。
对本机内存进行串行化/反序列化堆栈对象也是许多堆外存储库的作用。
但是如果选择合适的收藏家,他们可能并不是必需的。 CMS不会移动终身对象并且可以跳过大型原始数组,因此即使非常大的堆也不应该产生额外的GC成本,只要它们大多充满原始数组并且如果你设法调整GC以避免并发模式失败。
如果您想要在垃圾收集器的掌握之外使用完整的物体,那么就有jillegal。
正如其名称和文档所示,它深入到VM内部,并伴随着许多警告/前向兼容性问题。
如果您觉得在鲨鱼池旁做心脏直视手术是解决问题的最合理方法,那么只能使用它。
答案 3 :(得分:0)
反转逻辑,并将图形放在一个单独运行的数据库中。然后使用更易变的查询进行操作。这是否必须是图形数据库取决于( - 商业Neo4J?)。
你可以通过持久性来支付一些速度,并且在图形数据库的情况下可以使用快速查询语言&实施
答案 4 :(得分:0)
垃圾收集器在无法访问时在堆区域中收集/释放对象。 因此,为了排除垃圾收集器跟踪对象,您应始终具有该对象的引用ID(最佳情况是以强引用的形式)