当 JVM 在运行时内存不足时会发生什么情况?

在考虑了很长时间提出这个问题的通用方法(并且找不到一个)之后,我只是把它作为一个具体的例子来问:

假设我有一台Linux机器,它有1 Gb的内存,可以分配给进程(物理和交换总共1 Gb)。

我在计算机上安装了一个标准的 Oracle Hotspot JVM 版本 7。如果在给定的时刻,有足够的程序在运行,使得1 Gb中只有400 Mb是空闲的,那么我在那一刻启动了一个Java程序,并使用以下JVM标志:

java -Xms256m -Xmx512m -jar myJar.jar

发生了什么?:

A. JVM 无法立即启动,是因为它将尝试分配所有 512 Mb 的内存并失败(由于目前没有足够的可用内存)?

如果 JVM 启动:

如果在某些时候,正在运行的Java进程将需要超过400 Mb的内存(并且除了当前Java进程已经使用的内存之外,仍然只有400 Mb的内存可用),会发生什么:

B. Java 进程会因 OutOfMemroyError 而失败吗?

C.它会因其他(标准)错误而失败吗?

D.是未定义的行为吗?


答案 1

-Xmx 只是定义了堆的最大大小。它不能保证是否有这么多的内存。它只确保堆永远不会大于给定的值。也就是说,选项B。将会发生,将抛出一个超出内存的错误。


答案 2

假设我有一台Linux机器,它有1 Gb的内存,可以分配给进程(物理和交换总共1 Gb)。

我的第一反应是,除非你说的是手机,否则我会获得更多的内存。您可以以低于 100 美元的价格购买 16 GB(b = 位,B = 字节)。

JVM 是否无法立即启动,因为它将尝试分配所有 512 Mb 内存并失败(由于目前没有足够的可用内存)?

如果您的系统没有 512 MB(加上一些开销),因为它在启动时分配了用于堆的连续虚拟内存,则可能会发生这种情况。

即使您有 550 MB 的可用空间,程序也可能无法启动,因为它需要加载的不仅仅是堆。

Java 进程会因内存不足错误而失败吗?

如果程序在运行时使用 512 MB,则无论计算机具有多少内存量,都可能发生这种情况。此错误仅在 JVM 启动后发生。如果它无法启动,则不会收到此错误。

它会因其他(标准)错误而失败吗?

如果在程序启动后交换空间不足,这是可能的。这种情况很少见,只发生在严重过载的机器上。我所看到的是由于低级操作系统无法分配内存而导致的JVM崩溃。

Java 6 Update 25 VM 崩溃:内存不足