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

Joh*_*0te 2 java operating-system jvm

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

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

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

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

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

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

后续问题/评论

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

Nic*_*olt 5

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

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

来自JavaDoc OutOfMemoryError:

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

如果进程超出内存限制,特定于特定操作系统,则通常会从操作系统角度发生这种情况,但通常会终止进程.