【问题标题】:Java OutofMemory Error in Ubuntu Even if enough memory available即使有足够的可用内存,Ubuntu 中的 Java OutofMemory 错误
【发布时间】:2016-01-07 12:09:06
【问题描述】:

我有一个带有 20GB RAM、Ubuntu 操作系统的 VPS。我正在尝试使用 JAVA_TOOL_OPTIONS 将 10GB RAM 作为最大堆分配给 java,但我做不到。请参阅随附的屏幕截图。它显示可用内存为 17GB。当我尝试设置为 7GB 时它工作。但堆错误仅在 > 7GB 时发生。我已经安装了 glassfish 并为其集群分配了 3Gb。它工作正常。但是为什么我有 17GB 的可用 RAM 时却无法分配超过 7GB 的内存。

顶部

极限

Java 版本

过度提交内存

我的硬件是虚拟主机。下面是配置

  • 架构:x86_64
  • CPU 操作模式:32 位、64 位
  • 字节顺序:小尾数
  • CPU:16
  • 供应商 ID:正版英特尔
  • CPU 系列:6
  • 型号:26
  • 步进:5
  • CPU 频率:2266.802
  • BogoMIPS:4533.60
  • 虚拟化:VT-x

【问题讨论】:

  • 你能运行top看看还有什么在运行吗?如果还有什么..
  • 向我们展示运行java -version的输出;即您使用的是什么 Java 版本/构建?
  • 如果您使用的是 64 位版本的 java,那么您能检查一下您的 VPS 使用哪种硬件(主板)吗?
  • 检查ulimits,检查sysctl vm_overcommit,试试-XX:-UseLargePages
  • 我假设您使用的是 64 位版本的 java,因为 32 位版本会因为这个堆大小而失败。

标签: java memory jvm heap-memory


【解决方案1】:

如果我不得不猜测,您没有 7GB 的连续 RAM 块,这看起来确实很奇怪,但是如果不了解更多有关您的 VM 分配的信息,就很难说。

以下是甲骨文对此事的看法 (http://www.oracle.com/technetwork/java/hotspotfaq-138619.html#gc_oom):

VM 打印“OutOfMemoryError”并退出。增加最大堆大小 没有帮助。怎么回事?

如果内存不足,Java HotSpot VM 无法扩展其堆大小 完全分配,没有可用的交换空间。这可能发生, 例如,当多个应用程序同时运行时。 发生这种情况时,VM 将在打印类似的消息后退出 到以下。

异常 java.lang.OutOfMemoryError: 请求字节

-Xmx-Xms-Xmx

有关详细信息,请参阅错误 4697804 的评估部分。

【讨论】:

  • 罗宾,我使用的是 64 位。 “您没有连续的 RAM 块”是什么意思?你能解释一下吗?这个解释适用于 64 位吗?早些时候我有一台 32 GB 的专用机器,我成功地分配了 10 到 25 GB 没有任何问题......但是即使我有 16 GB 的保证 RAM,为什么我连 8 到 10 GB 的 VM 都不能分配?跨度>
  • 显示实际资源使用情况的后续编辑非常有说服力。斯蒂芬 C 的回答几乎总结了这一点;当页面文件空间(空闲 RAM)不足时,JVM 将使用虚拟内存(硬盘)。 JVM 如何决定何时与虚拟内存交换页面文件将取决于正在运行的进程。这就是为什么建议保留相当于系统 RAM 的硬盘交换空间,以确保页面文件可以交换。
  • 我忽略了说明“连续 RAM”。 RAM 被分配为页面文件。这些页面需要是一个连续的可寻址空间块。因此,即使您有很多 RAM,如果它的碎片化到没有足够大的内存来支持页面文件请求,那么您实际上是堆空间不足。我不知道 JVM 如何分配堆空间的初始请求,但如果它试图创建一个连续的块,以便它可以管理分页,那么你需要一个足够大的可寻址空间块。 7GB 是一个大块。
【解决方案2】:

我认为您的交换空间可能已用完。当我将“virt”列中的内存加起来时,它达到了 40+ Gb。


为什么要占用这么多交换空间?为了解决这个问题需要做什么?

好吧,根据top你正在运行:

  • 玻璃鱼 - 9.1G
  • MySQL 守护程序 - 5.4G
  • 哈德逊 - 8.9G
  • Nexus - 6G
  • Glassfish - 6.9G(第二次)

还有其他各种东西。 “virt”是它们的总虚拟内存占用,其中一些是可以共享的代码段。

目前它们似乎大多有一个小的“res”(常驻内存),这就是为什么有这么多空闲 RAM。但是,如果其中一些同时出现,系统对 RAM 的需求将会猛增,系统可能会开始崩溃。

我的建议是将 Hudson 和 Nexus 服务移至单独的 VM。或者,如果这不可行,请增加交换空间的大小……并希望您不要颠簸。


这是真的。但这是正常的行为吗?

是的。

这就是内存分配的工作原理吗?

是的。这确实是虚拟内存的工作原理。

我现在对常驻内存、虚拟内存和物理内存感到困惑。

我建议您先阅读virtual memory上的维基百科页面,而不是详细解释它。

【讨论】:

  • 为什么要占用这么多交换空间?为了解决这个问题需要做什么?
  • 但是为什么呢?我将最大大小为 3G 分配给 glassfish 第一个实例,将 1GB 分配给第二个实例。为什么要占用这么多空间?如何限制?我是否必须更改 vm.overcommit 比率和内存的配置?我也附上了截图。请告诉我如何解决此问题?
  • Stephen,正如你所说,一旦我停止了 nexus 和 hudson,我就设法启动了占用 3G 的 glassfish 的第二个实例。 They mostly seem to have a small "res" (resident memory) at the moment which is why there is so much free RAM. However, if a few of them sprang into life at the same time the system the demand for RAM would skyrocket, and the system might start to thrash. 这是真的。但这是正常的行为吗?这是内存分配的工作原理吗?我现在对常驻内存、虚拟内存和物理内存感到困惑。
  • 在第一个附件中可以发现,如果加上红色栏,不会超过3G。为什么虚拟内存加起来高达 40+G?如果 res 内存是真的,为什么它不允许我提供超过 10G 的内存?
  • 我有一个专用系统,在那个系统中,free 命令总是向我显示使用的正确数量的内存。但是为什么 VPS 会这样呢?
【解决方案3】:

我无法分配超过 5G 的原因是因为 privvmpages 设置为 5G。

我们可以在 linux 中通过这个命令 "cat /proc/user_beancounters" 获取这些信息

此外,在 VPS 中,托管服务提供商不允许我们自定义此值。我们必须选择大型虚拟服务器或专用服务器来增加此限制。

这是根本原因。然而,斯蒂芬和罗宾对虚拟内存和 RES 内存的解释是正确的。谢谢各位

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-29
    • 1970-01-01
    相关资源
    最近更新 更多