我有一台运行 Solaris 10 的服务器。它报告了 70+ GiB 的可用 RAM。我正在尝试在 64 位模式下使用 Java 1.7.0_80 启动 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
空闲 RAM 仅意味着其中没有存储任何内容。这并不意味着你可以使用它。报告的空闲 RAM 完全有可能不能被您的新 JVM 使用,因为其他应用程序已经保留了它。在任何情况下,JVM 就像大多数应用程序一样不要求 RAM,而是要求虚拟内存。这很可能是您的系统遇到的问题,即缺少虚拟内存。
您将使用该命令了解您的虚拟内存使用情况:
解决虚拟内存短缺的简单方法是增加(或创建)一个交换区域,以便为内存预留提供一个后备存储区域。
编辑:根据您发布的其他信息,您的应用程序无法分配更多虚拟内存的原因是因为您在内存上限到位的非全局区域中运行。非全局区域是容器,即它们都共享同一个内核。但是,可以限制它们的资源使用以防止一个区域干扰其他区域。
除了停止使用虚拟内存的其他进程之外,您无法在该区域执行任何操作,即使是 root 用户也是如此。您需要要求全局区域管理员为您的区域授予更多虚拟内存,在您的情况下是
zone.max-swap
设置。