如何启动具有较大最大堆的 Java 程序?
我使用一个用 Java 编写的占用大量内存的程序 (CrashPlan),有时在高峰使用时需要大约 1.5 GB 的内存(这由参数 -Xmx1500M 控制)。
通常(至少在启动时)它需要很少的内存,但如果低于 -Xmx1500M,它会在高峰使用时崩溃。启动后(使用 -Xmx1000M),任务管理器在工作集、私有集和已分配内存中显示其内存使用量约为 100 MB。
但是,Java VM 无法使用 -Xmx1500M 启动,我猜是因为它无法分配此内存。(使用 -Xmx1000M 时它确实启动了,但后来崩溃了。)
我使用的是 Windows 7 pro 32 位(不是 64 位),安装了 32 GB 内存(3 GB 可访问,页面文件位于不可访问内存中的大 RAM 磁盘上)。
我预计 Windows 会换出其他进程来为 Java 分配内存,而且由于 Java 反正也不用它,所以会将 Java 未使用的内存交换到页面文件。比如说,现在我看到 mydefrag 进程使用 1700 MB 分配集,没有任何问题。
(似乎直到上周它还是这样。然后情况发生了变化。)
我怎样才能强制 Java 以 -Xmx1500M 启动?
答案1
正如您已经意识到的,在 32 位 Windows 上,用户进程的可寻址内存限制为 2GB(4GB 地址空间的一半为操作系统保留)。但您还必须考虑到,堆内存并不是 Java-VM 使用的唯一内存类型:还有本机内存分配、堆栈空间、永久代、代码缓存等的要求。所有这些都必须来自相同的 2GB 可用空间。因此,确切的最大堆大小可能因 Java 版本而异(甚至可能因不同的计算机而异),但根据 Oracle 的说法
在大多数现代 32 位 Windows 系统上,最大堆大小范围为 1.4G 到 1.6G。
因此,对于任何需要 1.5 GB 堆的东西,在 32 位 JVM(以及 32 位操作系统)上你可能就运气不佳了。
您可能能够通过减少其他内存池来获得一些额外的 MB,例如通过设置-XX:ReservedCodeCacheSize
(默认 32m)或-XX:MaxPermSize
(默认 64m),但这可能会在运行应用程序时导致其他问题。