我有很多 JVM 在具有 32GB 物理内存和 32GB 虚拟内存的 Linux Redhat 上运行。这些 JVM 被配置为具有超过 32GB 的 Xmx 总值,并且可能让 Linux 使用了它的虚拟内存。
我的问题是,如果我指定的 Xmx 超过了所需的堆大小,它会延迟垃圾收集并因此分配比必要更多的堆大小吗?因此它将导致操作系统从其虚拟内存中分配内存,从而导致性能下降。
1 回答
JVM 在启动时保留最大堆大小(以及其他内存区域)。这意味着如果您的最大堆大小为 32 GB,它将使用大约 33-35 GB 的虚拟内存,包括共享库线程等。
如果您将最大堆大小设置为 32 GB,则它必须使用 64 位引用,并且与最大堆为 24 GB 且将使用 32 位引用的 JVM 相比,最终可用内存可能更少。有人估计,如果您将堆大小设置为 32 Gb 或更大,则必须将其增加到 48 GB 才能获得更多可用内存。
鉴于您机器的大小,我建议您将堆限制为 24 GB(或更少),并尽可能使用堆外内存,因为这可以同时具有性能优势和更大的可扩展性。
如果你有一个低 GC 程序并且你想避免收集,你可以创建一个巨大的伊甸园大小和 GC 每天或每周一次。为此,您必须将垃圾丢弃到最低限度,并且您可以创建一个 20 GB 的伊甸园大小,在这种情况下,如果您每天创建的垃圾少于 20 GB,您可以避免触发任何 GC(即使是次要的)并运行完整的 GC 作为通宵维护任务。例如凌晨 2 点。
如果您使用大堆,则要不惜一切代价避免使用交换。这是因为 GC 需要随机访问堆,并且一旦触发了足够大的交换,您的机器就会颠簸很长一段时间(可能是几个小时),并可能锁定。您甚至可能必须重新启动才能让您的机器正常运行。(很难杀死处于这种状态的进程/机器)