由于未释放 Linux RAM 磁盘缓存导致的 Java OutOfMemoryError

标签 java linux memory linux-kernel

进程会正常运行一整天,然后,砰,在没有警告的情况下,它会抛出这个错误。有时似乎无所事事。它会在一天中看似随机的时间发生。我检查了机器上是否正在运行其他任何东西,例如计划的备份或其他东西,但一无所获。机器有足够的物理内存(2GB,对于 3-500MB 的负载大约有 1GB 可用),并且指定了足够的 -Xmx。

根据我们的系统管理员,问题是当 JVM 需要分配内存时,内核用作磁盘缓存的 RAM(显然除了 8MB 之外的所有内存)没有被释放,因此 JVM 进程抛出 OutOfMemoryError。这可能是因为 Java 在分配之前询问内核是否有足够的内存可用,但发现内存不足,导致崩溃。

然而,我想认为,Java 只是尝试通过内核分配内存,当内核收到这样的请求时,它会通过抛出我们的一些磁盘缓存来为应用程序腾出空间。

有没有其他人遇到过这个问题,如果有,错误是什么,你是如何解决的? 我们目前在 VMWare ESX 中的 SLES 10 SP2 Linux 2.6.16.60-0.42.9-smp 上使用 jdk1.6.0_20。

最佳答案

According to our sysadmin, the problem is that the RAM that the kernel uses as a disk cache (apparently all but 8MB) is not freed when the JVM needs to allocate memory, so the JVM process throws an OutOfMemoryError.

我认为您的系统管理员搞错了。 Linux 将根据系统运行进程对物理内存的需求,自动透明地增大和缩小缓冲区高速缓存的大小。如果没有,则说明您的操作系统存在严重问题。

您的 Java 应用程序更有可能存在内存泄漏,导致它使用稳定增加的堆空间量。最终您会遇到 -Xmx 限制并获得 OOME。我将通过在启用 GC 日志记录的情况下运行应用程序来开始对此进行调查。这将告诉您堆如何随时间增长、GC 回收了多少空间等等。

另一种可能是您没有配置足够的交换空间。

关于由于未释放 Linux RAM 磁盘缓存导致的 Java OutOfMemoryError,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2882590/

相关文章:

java - 参数化类型

python - AWS + MongoDB : How to connect to mongo server on AWS linux instance?

c++ - 无符号窄字符类型数字表示

memory - Tomcat ThreadWithAttributes 导致内存泄漏

java - 如果您的 RDP 连接滞后,为什么 Java 服务器也会滞后?

java - 在 REST 端点上使用 throws 子句是否被认为是糟糕的设计?

ruby - LookController#at 中的参数错误

linux - 将文本复制到剪贴板,Linux,使其永久化

java - Java for 循环中分配的内存在循环后会被释放吗?

java - 如何向变量名称添加变量? java