java 程序在到达 xmx 之前内存不足

java 程序在到达 xmx 之前内存不足

在 Redhat CentOS 6.4 上,只有几个进程在运行,使用大约 3GB RAM(系统有 12GB 可用)。其中一个进程是 WSO2ESB 服务器(java),我们使用以下参数启动它:

 -Xms2048m -Xmx3072m

过了一会儿,我们得到了一个 OutOfMemory 异常,但是java 进程(WSO2ESB)甚至没有使用其 3GB。在 jconsole 中,您还可以看到这些参数设置正确(此时 Linux 服务器有大约 9GB 的可用 RAM)

Linux 没有给我们配置 3 GByte RAM 吗?

在完全相同的 Windows 安装上 - java 进程可以毫无问题地使用其 3GB Ram。

在此处输入图片描述 jconsole 的屏幕截图显示堆内存使用量仅在 0.3 到 1.0 GB 之间。在发生 OutOfMemory 异常时,堆内存为 0.5GB,但该进程可以使用 3GB,但它没有...

编辑:添加了 java 进程的日志:

java.lang.OutOfMemoryError: unable to create new native thread

EDIT2:添加了 free -m 输出: 在此处输入图片描述

答案1

我解决了这个问题。wso2esb 使用了超过 1000 个线程。但在 Linux 上,用户可以使用的默认线程数量设置为 1024。我不得不提高用户的限制,现在一切都正常了。

为此:打开 /etc/security/limits.conf 并为您的用户添加以下两行:

myuser             soft    nproc           8192
myuser             hard    nproc           8192

在此处输入图片描述

答案2

Java的堆空间有多个代,新生代、老生代。

如果您将 Xmx 设置得非常高,则它用于堆,即使您不使用整个堆,也可能会耗尽内存。如果您耗尽了 PermGen 空间,通常会发生这种情况。

永久代堆用于存储字符串池和 JVM 所需的与类、方法和其他 Java 原语相关的各种元数据。永久代空间通常为 64MB,因此如果您有很多类或巨大的字符串,您可能会用完它。

尝试通过添加以下内容来增加 permgen 的大小:

-XX:MaxPermSize=256m

到您的 java 启动选项。

答案3

堆的数据段大小是多少-Xms2048m -Xmx3072m

您的数据段大小应与您的最大堆大小相对应(在本例中为 3072m)。因此,您的数据段大小应至少设置为3221225472(以字节为单位 3*1024*1024*1024 = 3GB)

相关内容