当JVM在运行时耗尽内存时会发生什么?

时间:2012-11-07 13:37:44

标签: java memory memory-management garbage-collection jvm

在思考了一个通用的方法来提出这个问题(并且没有找到一个)后,我只想问它是一个具体的例子:

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

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

java -Xms256m -Xmx512m -jar myJar.jar
发生了什么事? :

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

如果JVM启动:

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

B中。 Java进程是否会因OutOfMemroyError而失败?

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

d。这是不确定的行为?

5 个答案:

答案 0 :(得分:9)

-Xmx只定义堆的最大大小。它不能保证有这么多的记忆。它只能确保堆永远不会比给定值大。也就是说,选项B。将会发生,将抛出outOfMemoryError。

答案 1 :(得分:7)

  

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

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

  

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

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

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

  

Java进程是否会因OutOfMemoryError而失败?

如果您的程序在运行时使用512 MB,无论您的计算机具有多少内存,都会发生这种情况。只有在JVM启动后才会出现此错误。如果无法启动,您将不会收到此错误。

  

是否会因其他(标准)错误而失败?

如果程序启动后用尽了交换空间,则可以执行此操作。这是罕见的,只发生在严重超载的机器上。我所看到的是由于低级操作系统无法分配内存而导致JVM崩溃。

Java 6 Update 25 VM crash: insufficient memory

答案 2 :(得分:2)

OutOfMemroyError“当Java虚拟机无法分配对象时抛出,因为内存不足,垃圾收集器无法再提供更多内存。” < / p>

所以,实质上,“B。Java进程失败并带有OutOfMemroyError

答案 3 :(得分:2)

如果占用的内存太大,以至于可用空间甚至无法维持空闲的JVM,那么你会得到一些错误,说程序内存不足,或者JVM会崩溃。

如果可以运行JVM,则可以使用-Xmx指定堆空间限制。这并不意味着JVM在启动时将分配所有堆 - 它只是一个内部限制。如果JVM想要增加堆空间,但没有足够的内存,或者需要的堆比-Xmx指定的堆多,那么在当前运行的Java程序中会出现OutOfMemoryError。

在非常极端的情况下,在JVM运行时可能会耗尽可用内存,同时JVM需要更多内存用于其内部操作(而不是堆空间) - 然后JVM会告诉您需要它

。更多内存,但无法获取,终止,或者它会彻底崩溃。

答案 4 :(得分:1)

JVM进程将在虚拟内存中运行,因此运行其他进程的分配问题是相关的,但不是完全确定的。

当JVM无法分配更多内存(无论出于何种原因)时,进程本身不会终止,而是开始在 JVM中抛出OutOfMemoryError ,而不是在JVM外部抛出。换句话说,JVM继续运行,但JVM中运行的程序通常会失败,因为大多数程序都不能充分处理低内存条件。在这种相当常见的情况下,当程序没有做任何事情来处理错误时,JVM将终止程序并退出。最终,这是来自内存分配,但不是直接的。一段代码可以在低内存条件下自行扩展并继续运行。

其他人已经指出,有时JVM本身并不能很好地处理低内存,但这是一个相当极端的条件。