我有一台运行 Solaris 10 的服务器。它报告有 70+ GiB 可用 RAM。我尝试使用 Java 1.7.0_80 以 64 位模式启动 Tomcat 7.0.68。
服务器声称无法分配 717 MiB 的 RAM。每次尝试时,我都会收到一个 hs_err_pidxxx.log 文件。它表明:
# There is insufficient memory for the Java Runtime Environment to continue.
# Native memory allocation (malloc) failed to allocate 717225984 bytes for committing reserved memory.
# Possible reasons:
# The system is out of physical RAM or swap space
不。有 70 GiB 可用,它正尝试分配 700ish MiB。
# In 32 bit mode, the process size limit was hit
我们处于 64 位模式。
# Possible solutions:
# Reduce memory load on the system
这台机器上除了操作系统之外没有别的东西。
# Increase physical memory or swap space
我们已经超出了需要的两个数量级。
# Check if swap backing store is full
不。
# Use 64 bit Java on a 64 bit OS
完毕。
# Decrease Java heap size (-Xmx/-Xms)
如果可以的话我会的。
# Decrease number of Java threads
这是怎么做到的?
# Decrease Java thread stack sizes (-Xss)
建议值?这是默认值,但我不知道该如何调整它。
# Set larger code cache with -XX:ReservedCodeCacheSize=
再次,我们处于默认状态。
$ swap -s
total: 48607296k bytes allocated + 18201336k reserved = 66808632k used, 311770552k available
答案1
可用 RAM 只是意味着其中没有存储任何内容。这并不意味着您可以使用它。报告为可用 RAM 完全有可能无法由新 JVM 使用,因为其他应用程序已将其保留。无论如何,JVM 与大多数应用程序一样,不会请求 RAM,而是请求虚拟内存。这很可能是您的系统遇到的问题,即缺乏虚拟内存。
您可以使用以下命令了解虚拟内存的使用情况:
swap -s
解决虚拟内存短缺问题的简单方法是增加(或创建)一个交换区域,以便内存预留有备用存储区域。
编辑:根据您发布的附加信息,您的应用程序无法分配更多虚拟内存的原因是由于您正在运行一个非全局区域,并且该区域内存上限已到位。非全局区域是容器,即它们都共享同一个内核。但是,可以限制它们的资源使用,以防止一个区域干扰其他区域。
除了停止使用虚拟内存的其他进程外,您无法从此区域执行任何操作,即使以 root 身份也是如此。您需要请求全局区域管理员为您的区域授予更多虚拟内存,在您的情况下zone.max-swap
设置。