java 为什么我可以在 Windows 和 Solaris 上将 -Xmx 设置为大于计算机上物理和虚拟内存的值?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1949904/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 18:40:45  来源:igfitidea点击:

Why am I able to set -Xmx to a value greater than physical and virtual memory on the machine on both Windows and Solaris?

java

提问by ariscris

On a 64-bit Windows machine with 12GB of RAM and 33GB of Virtual Memory (per Task Manager), I'm able to run Java (1.6.0_03-b05) with an impossible -Xmx setting of 3.5TB but it fails with 35TB. What's the logic behind when it works and when it fails? The error at 35TB seems to imply that it's trying to reserve space at startup. Why would it do that for -Xmx (as opposed to -Xms)?

在具有 12GB RAM 和 33GB 虚拟内存(每个任务管理器)的 64 位 Windows 机器上,我能够运行 Java (1.6.0_03-b05) 并且 -Xmx 设置为 3.5TB,但它以 35TB 失败. 什么时候起作用,什么时候失败,背后的逻辑是什么?35TB 的错误似乎暗示它试图在启动时保留空间。为什么它会为 -Xmx(而不是 -Xms)这样做?

C:\temp>java -Xmx3500g ostest  
os.arch=amd64  
13781729280 Bytes RAM

C:\temp>java -Xmx35000g ostest  
Error occurred during initialization of VM  
Could not reserve enough space for object heap  
Could not create the Java virtual machine. 

On Solaris (4GB RAM, Java 1.5.0_16), I pretty much gave up at 1 PB on how high I can set -Xmx. I don't understand the logic for when it will error out on the -Xmx setting.

在 Solaris(4GB RAM,Java 1.5.0_16)上,我几乎放弃了 1 PB 我可以设置多高的 -Xmx。我不明白什么时候会在 -Xmx 设置上出错的逻辑。

devsun1.mgo:/export/home/mgo> java -d64 -Xmx1000000g ostest
os.arch=sparcv9
4294967296 Bytes RAM

回答by jarnbjo

At least with the Sun 64-bit VM 1.6.0_17 for Windows, ObjectStartArray::initialize will allocate 1 byte for each 512 bytes of heap on VM startup. Starting the VM with 35TB heap will cause the VM to allocate 70GB immediately and hence fail on your system.

至少对于适用于 Windows 的 Sun 64 位 VM 1.6.0_17,ObjectStartArray::initialize 将在 VM 启动时为每 512 个字节的堆分配 1 个字节。使用 35TB 堆启动 VM 将导致 VM 立即分配 70GB,因此在您的系统上失败。

The 32-bit VM (and so I suppose the 64-bit VM) from Sun does not take account for available physical memory when calculating the maximum heap, but is only limited by the 2GB addressable memory on Windows and Linux or 4GB on Solaris or possibly failing to allocate enough memory at startup for the management area.

Sun 的 32 位 VM(因此我认为是 64 位 VM)在计算最大堆时不考虑可用物理内存,但仅受 Windows 和 Linux 上的 2GB 可寻址内存或 Solaris 上的 4GB 或可能无法在启动时为管理区分配足够的内存。

If you think about it, checking the sanity of the max heap value against available physical memory does not make much sense. X GB of physical memory does not mean that X GB is available to the VM when required, it can just as well have been used by other processes, so the VM needs a way to cope with the situation that more heap is required than available from the OS anyway. If the VM is not broken, OutOfMemoryErrors are thrown if memory cannot be allocated from the OS, just as if the max heap size has been reached.

如果您考虑一下,根据可用物理内存检查最大堆值的合理性并没有多大意义。X GB 的物理内存并不意味着 X GB 在需要时可供 VM 使用,它也可以被其他进程使用,因此 VM 需要一种方法来应对需要的堆比可用的堆多的情况反正操作系统。如果 VM 没有损坏,并且无法从操作系统分配内存,则抛出 OutOfMemoryErrors,就像已达到最大堆大小一样。

回答by Pascal Thivent

According to this threadon Sun's java forums (the OP has 16GB of physical memory):

根据Sun 的 java 论坛上的这个帖子(OP 有 16GB 的物理内存):

You could specify -Xmx20g, but if the total of the memory needed by all the processes on your machine ever exceeds the physical memory on your machine, you are likely to end up paging. Some applications can survive running in paged memory, but the JVM isn't one of them. Your code might run okay, but, for example, garbage collections will be abysmally slow.

您可以指定 -Xmx20g,但是如果您机器上所有进程所需的内存总量超过了您机器上的物理内存,您很可能会以分页结束。有些应用程序可以在分页内存中运行,但 JVM 不是其中之一。您的代码可能运行良好,但是,例如,垃圾收集将非常缓慢。

UPDATE:I googled a bit further and, according to the Frequently Asked Questions About the Java HotSpot VMand more precisely How large a heap can I create using a 64-bit VM?

更新:我进一步搜索了一下,根据关于 Java HotSpot VM 的常见问题,更准确地说,我可以使用 64 位 VM 创建多大的堆?

How large a heap can I create using a 64-bit VM?

On 64-bit VMs, you have 64 bits of addressability to work with resulting in a maximum Java heap size limited only by the amount of physical memory and swap space your system provides.
See also Why can't I get a larger heap with the 32-bit JVM?

使用 64 位 VM 可以创建多大的堆?

在 64 位 VM 上,您可以使用 64 位寻址能力,从而导致最大 Java 堆大小仅受系统提供的物理内存和交换空间量的限制。
另请参阅为什么我不能使用 32 位 JVM 获得更大的堆?

I don't know why you are able to start a JVM with a heap >45GB. This is a bit confusing...

我不知道为什么您可以启动堆大于 45GB 的 JVM。这有点混乱...

回答by Bill K

Just to re-enforce Pascal's answer--Be very careful in windows when specifying a high max memory size. I was working on a server project that required as much physical memory as possible, but once you are over physical ram, abysmal performance is not a good description of what happens--Hung machine might be better.

只是为了重新执行 Pascal 的回答——在指定高最大内存大小时在 Windows 中要非常小心。我正在处理一个需要尽可能多的物理内存的服务器项目,但是一旦你超过物理内存,糟糕的性能就不能很好地描述发生的事情——挂机可能会更好。

What happens (at least this is my evaluation of it after days of examining logs and re-running tests) is, Windows runs out of ram and asks all apps to free up what they can. When it asks Java, Java kicks off a GC. The GC touches all of memory (causing anything that has been swapped out to be swapped in). This in turn causes windows to run out of memory. Windows then sends a message to all apps asking them to free up what they can.... (recurse indefinitely)

会发生什么(至少这是我在检查日志和重新运行测试后对它的评估)是,Windows 耗尽了 ram 并要求所有应用程序释放它们所能释放的空间。当它询问 Java 时,Java 启动 GC。GC 触及所有内存(导致任何已换出的东西都被换入)。这反过来会导致 Windows 内存不足。然后 Windows 向所有应用程序发送一条消息,要求他们释放他们所能释放的内容......(无限期递归)

This may not ACTUALLY be what is going on, but the fact that Java GC touches Very Old Memory at times makes it incompatible with paging.

这实际上可能不是正在发生的事情,但 Java GC 有时会触及非常旧的内存这一事实使其与分页不兼容。