垃圾收集器调优
本页讨论了 Java 虚拟机垃圾收集器对 Neo4j 性能的影响。在这种设置下,堆被分为老年代和新生代,新对象在新生代中分配,如果它们存活(在使用)足够长时间,则随后被移到老年代。
当一个代填满时,垃圾收集器会执行一次收集,在此期间进程中的所有其他线程都会暂停。新生代收集速度快,因为暂停时间与对象的活跃集相关。在老年代中,暂停时间大致与堆的大小相关。因此,理想情况下,堆的大小和调优应确保事务和查询状态永远不会进入老年代。
堆大小通过 neo4j.conf 文件中的 server.memory.heap.initial_size
(以 MB 为单位)设置进行配置。堆的初始大小由 server.memory.heap.initial_size
设置指定,或通过 -Xms???m
标志指定,如果未指定,则由 JVM 启发式选择。JVM 会根据需要自动增长堆,直至达到最大大小。堆的增长需要一个完整的垃圾收集周期。建议将初始堆大小和最大堆大小设置为相同的值。这样可以避免垃圾收集器增长堆时发生的暂停。
如果新生代过小,短生命周期的对象可能会过早地被移到老年代。这被称为过早晋升,会增加老年代垃圾收集周期的频率,从而降低数据库速度。如果新生代过大,垃圾收集器可能会认为老年代没有足够的空间来容纳它预期从新生代晋升到老年代的所有对象。这会将新生代垃圾收集周期转变为老年代垃圾收集周期,再次降低数据库速度。运行更多并发线程意味着在给定时间内可以进行更多分配,从而特别增加了新生代的压力。
JVM 中的 Compressed OOPs 功能允许对象引用被压缩以仅使用 32 位。此功能节省大量内存,但仅适用于高达 32 GB 的堆。最大适用大小因平台和 JVM 版本而异。可以使用 |
如何调优特定的垃圾收集算法取决于 JVM 版本和工作负载。建议在实际负载下测试垃圾收集设置数天或数周。堆碎片等问题可能需要很长时间才能显现。
为了获得良好的性能,以下是首先要考虑的事项
-
确保 JVM 没有花费过多时间执行垃圾收集。目标是拥有足够大的堆,以确保重负载/高峰负载不会导致所谓的 GC 抖动(GC-trashing)。当发生 GC 抖动时,性能可能会下降多达两个数量级。堆过大也可能损害性能,因此您可能需要尝试不同的堆大小。
-
Neo4j 需要足够的堆内存来处理事务状态和查询处理,以及为垃圾收集器留出一些余量。由于堆内存需求非常依赖于工作负载,因此常见的堆内存配置范围从 1 GB 到 32 GB。
编辑以下属性
属性名称 | 含义 |
---|---|
|
初始堆大小(MB) |
|
最大堆大小(MB) |
|
附加的字面 JVM 参数 |