【问题标题】:When do out of memory exceptions actually occur in Java?Java中什么时候真正发生内存不足异常?
【发布时间】:2014-04-15 04:58:57
【问题描述】:

我正在发布对this 问题的答案,但我意识到我对某些事情感到困惑。我问了几个熟悉 Java 的同事,我们都有点难过。

在这种情况下会发生什么:

  1. 启动 JVM,启动大小为 512MB,最大大小为 2GB。
  2. 您的底层操作系统剩余 1GB 内存,因此允许 JVM 启动。
  3. 您的程序使用了超过 1GB 的内存。

此时,您已经使用了所有可用的 JVM 内存,但您还没有违反在启动时设置的 JVM 内存限制。操作系统限制了您获取更多资源的能力,而不是 JVM 本身。

我原以为这会导致OutOfMemoryError,如果您超出了 2GB JVM 大小限制,您会得到。不过我不得不承认,在实践中,当我们在服务器上运行太多进程时,我往往会看到速度变慢并且没有内存异常。

请注意,我知道分页,当内存耗尽时,进程会在 Linux 中被终止。我很想知道在 JVM 级别是否存在任何可能导致更多阻塞效应的额外机制,因为这是另一个问题中的人在他的评论中提出的问题。我意识到答案可能只是“不,没有其他机制到位。”

后续问题/意见

这是因为除非您达到实际的 JVM 内存限制,否则不会引发内存异常?如果是这样,当操作系统在没有达到其限制时无法为 JVM 提供更多内存时会发生什么?在操作系统内存可用之前,是否存在某种阻塞或类似机制?

【问题讨论】:

  • 嗯,有需求分页,还有交换空间;如果您完全耗尽操作系统内存,您不会看到 OOM,操作系统只会终止您的进程 - 或另一个进程:p
  • 是的,我知道分页,当内存耗尽时,Linux 中的进程会被终止。我很想知道在 JVM 级别是否存在任何可能导致更多阻塞效应的额外机制,因为这是另一个问题中的人在他的评论中提出的问题。
  • 嗯,可以限制每个线程的最大堆栈大小,是的;但在这种情况下,您将获得StackOverflowError,而不是OutOfMemoryError...除非操作系统资源本身已用尽。

标签: java operating-system jvm


【解决方案1】:

所有现代操作系统都使用page caching,数据在内存和磁盘之间交换。虽然有点过于简单化了,但每个进程都受可用地址数量(通常为 232 或 264)的限制,而不是物理内存量。

服务器在负载下开始运行缓慢的原因之一是它必须更频繁地交换数据,这涉及到相对较慢的磁盘读取。

来自OutOfMemoryError 的 JavaDoc:

当 Java 虚拟机无法分配对象时抛出,因为 内存不足,无法再提供内存 垃圾收集器。

从操作系统的角度来看,如果进程超出内存限制会发生什么,特定于特定的操作系统,但通常会终止进程。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-12-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-29
    • 1970-01-01
    相关资源
    最近更新 更多