拆分堆(仅适用于 Windows,不推荐使用)

许多 Java™ 应用程序工作负载取决于 Java 堆大小。 SDK 可以使用分割堆来绕过 32 位 Windows 内存空间中的限制,并提供更大的最大堆大小。 此功能对于必须在 32 位 JVM 上运行 (例如,由于 32 位 JNI 库, 32 位操作系统或 32 位硬件) 但需要大型 Java 堆的应用程序很有用。

注: -Xgc:splitheap 命令行选项在 V 8 中已不推荐使用,并且将从 IBM SDK 的未来版本中除去。

Windows 地址空间中的中断将 Java 堆限制为小于 2 GB。 使用分割堆以允许 Java 堆存在于地址空间中断的两侧。 与使用一个连续的内存区域相比,您或许能够分配一个更大的堆。 通过使用更大的堆,在引发垃圾回收之前您可以分配更多的对象,并且您可以在发生 OutOfMemoryError 异常之前,增加可使用的活动对象的数目。

使用 -Xgc:splitheap 命令行选项 (仅在 Windows 32 位 JVM 上可用) 来启用分割堆。 当您使用此选项时,还会启用以下行为:
  • 强制垃圾收集器使用 gencon(分代并发)垃圾回收策略。
  • 分代 Java 堆的新区域和旧区域在单独的内存区域中进行分配。
  • 已禁用调整新内存区域和旧内存区域的大小。
如果应用程序按下列任何方式运行,那么建议不要使用拆分堆:
  • 在分代并发垃圾回收策略下,执行效果差。
  • 装入大量的类。
  • 在 JNI 库中使用大量本机系统内存; 增加的大小 Java 堆可能会保留过多的应用程序地址空间。
限制: 除非在 boot.ini 文件中指定了 /3GB 选项,否则 Windows 32 位进程将限制为 2 GB 地址空间。 有关更多信息,请参阅 SDK 用户指南 中的 Windows 32 位大地址感知支持

对于拆分堆,旧区域将在内存的较低区域中落实到其最大大小(使用 -Xmox 进行设置),而新区域将在内存的较高区域中落实到其最大大小(使用 -Xmnx 进行设置)。

分配故障

使用分割堆,JVM 可能会以更多方式在启动时失败。 分配分割堆失败将导致出现以下消息:
JVMJ9GC064 未能分配旧空间
在较低的内存中没有足够的可用空间来分配旧区域。 要解决此问题,请减少 -Xmox
JVMJ9GC065 未能分配新空间
在较高的内存中没有足够的可用空间来分配新区域。 要解决此问题,请减少 -Xmnx
JVMJ9GC066 未能分配所需的拆分堆内存结构
将新区域分配在低于旧区域的位置。 要解决此问题,请减少 -Xmx

最大堆大小

典型最大堆大小如下所示:

使用 32–bit JVM 的 32 位硬件上的 Windows 7 32 位
旧区域 1800 MiB,新区域 1000 MiB。
-Xgc:splitheap -Xmx2800m -Xmox1800m
使用 32–bit JVM 的 64 位硬件上的 Windows 7 64 位
旧区域 1700 MiB,新区域 2000 MiB。
-Xgc:splitheap -Xmx3700m -Xmox1700m

如果应用程序装入了大量类、装入了大量本机库或启动了多个线程,那么它们将具有更低的限制。