垃圾回收器调优

本页讨论了 Java 虚拟机垃圾回收器对 Neo4j 性能的影响。在此设置中,堆被分成一个“老年代”和一个“年轻代”,新的对象分配在年轻代中,如果它们在足够长的时间内保持活动(使用),则稍后被移动到老年代。

当一个代满时,垃圾回收器会执行一个收集,在此期间进程中的所有其他线程都会暂停。年轻代收集速度很快,因为暂停时间与对象的“活动集”相关。在老年代中,暂停时间大约与堆的大小相关。因此,理想情况下,堆的大小和调优应使得事务和查询状态永远不会进入老年代。

堆大小通过neo4j.conf文件中的server.memory.heap.initial_size(以MB为单位)设置配置。堆的初始大小由server.memory.heap.initial_size设置指定,或者使用-Xms???m标志指定,或者如果未指定则由JVM本身启发式选择。JVM会根据需要自动扩展堆,直到达到最大大小。堆的增长需要一个完整的垃圾回收周期。建议将初始堆大小和最大堆大小设置为相同的值。这样可以避免垃圾收集器扩展堆时发生的暂停。

如果新生代太小,短命对象可能会过早地移动到老年代。这被称为过早晋升,会导致老年代垃圾回收周期的频率增加,从而减慢数据库速度。如果新生代太大,垃圾收集器可能会认为老年代没有足够的空间来容纳所有它期望从新生代晋升到老年代的对象。这会将新生代垃圾回收周期变为老年代垃圾回收周期,同样会减慢数据库速度。运行更多并发线程意味着在给定时间段内可以进行更多分配,从而特别增加新生代的压力。

JVM 中的压缩 OOPs 功能允许对象引用被压缩为仅使用 32 位。该功能可以节省大量内存,但仅适用于高达 32 GB 的堆。最大适用大小因平台和 JVM 版本而异。-XX:+UseCompressedOops 选项可用于验证系统是否可以使用压缩 OOPs 功能。如果不能,这将在默认进程输出流中记录。

如何调整特定的垃圾回收算法取决于 JVM 版本和工作负载。建议在真实负载下测试垃圾回收设置几天或几周。堆碎片等问题可能需要很长时间才能显现出来。

要获得良好的性能,首先要查看以下内容

  • 确保 JVM 不花费太多时间进行垃圾回收。目标是拥有一个足够大的堆,以确保高负载/峰值负载不会导致所谓的 GC 浪费。GC 浪费发生时,性能可能会下降两个数量级。堆太大也可能损害性能,因此您可能需要尝试不同的堆大小。

  • Neo4j 需要足够的堆内存用于事务状态和查询处理,再加上一些用于垃圾收集器的空间。由于堆内存需求与工作负载密切相关,因此常见的堆内存配置从 1 GB 到 32 GB 不等。

编辑以下属性

表 1. neo4j.conf JVM 调整属性
属性名称 含义

server.memory.heap.initial_size

初始堆大小(以 MB 为单位)

server.memory.heap.max_size

最大堆大小(以 MB 为单位)

server.jvm.additional

附加的文字 JVM 参数