什么时候内存异常实际上发生在Java中?

时间:2014-03-11 14:06:44

标签: java operating-system jvm

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

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

  1. 启动JVM,启动大小为512MB,最大大小为2GB。
  2. 您的底层操作系统剩余1GB内存,因此允许JVM启动。
  3. 您的程序使用超过1GB的内存。
  4. 此时,您已使用所有可用的JVM内存,但是您没有违反在启动时设置的JVM内存限制。操作系统限制了您获取更多资源的能力,而不是JVM本身。

    我原本以为这会导致OutOfMemoryError,如果你超过2GB JVM大小限制就会得到。不过我必须承认, 在实践中 当我们在服务器上运行太多进程时,我倾向于看到减速并且没有内存异常。

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

    后续问题/评论

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

1 个答案:

答案 0 :(得分:5)

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

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

来自OutOfMemoryError的JavaDoc:

  

当Java虚拟机无法分配对象时抛出,因为   内存不足,没有更多的内存可供使用   垃圾收集器。

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