拆分堆(仅适用于 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
如果应用程序装入了大量类、装入了大量本机库或启动了多个线程,那么它们将具有更低的限制。