问题不在于32位操作系统上的最大堆大小,因为32位操作系统的最大可寻址内存大小为4GB,并且JVM的最大堆大小取决于可以保留多少连续空闲内存.
我更感兴趣的是知道在64位操作系统中运行的32位JVM的最大(理论上和实际可实现的)堆大小.基本上,我正在寻找与SO相关问题中的数字类似的答案.
至于为什么使用32位JVM而不是64位JVM,原因不是技术性的,而是行政/官僚性的 - 在生产环境中安装64位JVM可能为时已晚.
mik*_*ike 88
你可以问Java Runtime:
public class MaxMemory {
public static void main(String[] args) {
Runtime rt = Runtime.getRuntime();
long totalMem = rt.totalMemory();
long maxMem = rt.maxMemory();
long freeMem = rt.freeMemory();
double megs = 1048576.0;
System.out.println ("Total Memory: " + totalMem + " (" + (totalMem/megs) + " MiB)");
System.out.println ("Max Memory: " + maxMem + " (" + (maxMem/megs) + " MiB)");
System.out.println ("Free Memory: " + freeMem + " (" + (freeMem/megs) + " MiB)");
}
}
Run Code Online (Sandbox Code Playgroud)
这将根据默认堆分配报告"Max Memory".所以你仍然需要玩-Xmx
(在HotSpot上).我发现在Windows 7 Enterprise 64位上运行,我的32位 HotSpot JVM最多可以分配1577MiB:
[C:scratch]> java -Xmx1600M MaxMemory Error occurred during initialization of VM Could not reserve enough space for object heap Could not create the Java virtual machine. [C:scratch]> java -Xmx1590M MaxMemory Total Memory: 2031616 (1.9375 MiB) Max Memory: 1654456320 (1577.8125 MiB) Free Memory: 1840872 (1.75559234619 MiB) [C:scratch]>
而在同一操作系统上使用64位 JVM,当然它要高得多(大约3TiB)
[C:scratch]> java -Xmx3560G MaxMemory Error occurred during initialization of VM Could not reserve enough space for object heap [C:scratch]> java -Xmx3550G MaxMemory Total Memory: 94240768 (89.875 MiB) Max Memory: 3388252028928 (3184151.84297 MiB) Free Memory: 93747752 (89.4048233032 MiB) [C:scratch]>
正如其他人已经提到的,它取决于操作系统.
对于64位主机操作系统,如果JVM是32位,它仍将依赖,最有可能如上所示.
- 更新20110905:我只想指出其他一些意见/细节:
Runtime.MaxMemory
可以分配的实际数量还取决于操作系统的工作集.我曾经运行过这个,同时我也运行了VirtualBox,发现我无法成功启动HotSpot JVM -Xmx1590M
并且必须更小.这也意味着你可能会得到超过1590M,具体取决于你当时的工作集大小(尽管由于Windows的设计,我仍然保持32位以下的2GiB)Tho*_*sen 66
期望具有单个大块内存并使用原始指针的32位JVM不能使用超过4 Gb(因为这是32位限制,也适用于指针).这包括Sun和 - 我很确定 - 也是IBM的实现.我不知道例如JRockit或其他人是否有32位实现的大内存选项.
如果您希望达到此限制,则应该强烈考虑为生产环境启动并行跟踪验证64位JVM,以便在32位环境出现故障时为此做好准备.否则你将不得不在压力下完成这项工作,这绝不是好事.
编辑2014-05-15:Oracle FAQ:
32位JVM的最大理论堆限制为4G.由于各种附加约束,例如可用交换,内核地址空间使用,内存碎片和VM开销,实际上限制可以低得多.在大多数现代32位Windows系统上,最大堆大小范围为1.4G到1.6G.在32位Solaris内核上,地址空间限制为2G.在运行32位VM的64位操作系统上,最大堆大小可能更高,在许多Solaris系统上接近4G.
(http://www.oracle.com/technetwork/java/hotspotfaq-138619.html#gc_heap_32bit)
For*_*ner 16
您没有指定哪个操作系统.
在Windows下(对于我的应用程序 - 一个长期运行的风险管理应用程序),我们观察到在Windows 32bit上我们不能超过1280MB.我怀疑在64位下运行32位JVM会有什么不同.
我们将应用程序移植到Linux上,我们在64位硬件上运行32位JVM,并且运行起来非常容易.
您可能遇到的最大问题是GC取决于您使用的内存.
dja*_*fan 14
从4.1.2堆大小:
"对于32位进程模型,进程的最大虚拟地址大小通常为4 GB,但某些操作系统将此限制为2 GB或3 GB.对于2 GB限制,最大堆大小通常为-Xmx3800m(1600m)虽然实际限制是依赖于应用程序的.对于64位进程模型,最大值基本上是无限制的."
这里找到了一个很好的答案:Windows XP上的Java最大内存.
chi*_*nto 12
我们最近有过这方面的经验.我们最近从Solaris(x86-64版本5.10)移植到Linux(RedHat x86-64)并且已经意识到我们在Linux上的可用内存比用于Linux的32位JVM进程少.
对于Solaris,这几乎达到了4GB(http://www.oracle.com/technetwork/java/hotspotfaq-138619.html#gc_heap_32bit).
我们使用-Xms2560m -Xmx2560m -XX运行我们的应用程序:MaxPermSize = 512m -XX:PermSize = 512m,过去几年在Solaris上没有问题.试图将它移动到Linux,我们遇到启动时随机内存不足错误的问题.我们只能让它始终在-Xms2300 -Xmx2300上启动.然后我们被支持告知了这一点.
Linux上的32位进程的最大可寻址地址空间为3gb(3072mb),而在Solaris上则为4gb(4096mb).
64位操作系统上32位JVM的限制与32位操作系统上32位JVM的限制完全相同.毕竟,32位JVM将在32位虚拟机中运行(在虚拟化意义上),因此它不会知道它在64位操作系统/机器上运行.
在64位操作系统上运行32位JVM与在32位操作系统上运行的一个优点是,您可以拥有更多的物理内存,因此会更频繁地遇到交换/分页.但是,当您有多个进程时,这个优势才能真正完全实现.
小智 6
至于为什么使用32位JVM而不是64位JVM,原因不是技术性的,而是行政/官僚......
当我为BEA工作时,我们发现平均应用程序实际上在64位JVM中运行较慢,然后在32位JVM中运行时运行得很慢.在某些情况下,性能损失高达25%.因此,除非您的应用程序确实需要所有额外的内存,否则最好设置更多的32位服务器.
我记得,使用BEA专业服务人员遇到的64位最常见的三个技术理由是:
.