8 种 Java - 内存溢出六 - Out of swap space?

本文最后更新于:2024年7月25日 下午

6.1 Out of swap space? 概述

在启动时,Java 应用会分配有限的内存。这个限制是通过 -Xmx 和其他类似的启动参数指定。在这种场景: JVM 申请的总内存大于可用的物理内存,操作系统开始把这些内存从内存 swap out 到硬盘 (分配到 swap 区).

java.lang.OutOfMemoryError: Out of swap space? 错误意味着 swap 区也耗尽,新尝试的分配由于物理内存和 swap 区的不足而导致失败.

6.2 原因

当来自 native heap 的分配内存请求请求失败,且 native heap 接近用尽,JVM 抛出 java.lang.OutOfMemoryError: Out of swap space?. 这消息表明分配内存大小失败,内存请求的原因.

该问题发生在这样的场景: Java 进程开始启用 swapping, 这已经不是一个好的情况了。现在的 GC 策略很不错,但是当面临由 swapping 引起的延迟问题,GC 暂停会增加到大部分应用都服务法接受的级别.

java.lang.OutOfMemoryError: Out of swap space? 通常是由于操作系统层面的问题引起的,例如:

  • 操作系统 swap 区空间配置不足
  • 系统上的另一个进程消耗了所有的内存资源

也有可能是因为 native 泄漏导致的应用失败,例如,如果应用或库代码持续消耗内存但是却不释放内存到操作系统.

6.3 解决方案

要克服这个问题,你有几种方案。首先,最常用的而且是最容易的方案是增加 swap 区。这与平台有关,例如在 Linux 中你可以使用下面的命令来实现,它创建并挂载一个新的 swapfile —— 大小为 640 mb。

1
2
3
4
swapoff -a
dd if=/dev/zero of=swapfile bs=1024 count=655360
mkswap swapfile
swapon swapfile

现在,您应该回忆一下之前的内容,由于垃圾收集清除内存内容,一般来说,对于 Java 进程,交换 (swapping) 是不受欢迎的。 在交换分配 (swapped allocations) 上运行垃圾收集算法会增加好几个数量级的 GC 暂停时间,所以在跳到这个简单解决方案的时候,你应该三思而后行。

如果您的应用程序部署在与需要竞争资源的 “扰民恶邻” 的 JVM 的旁边,那么您应该将服务隔离到独立的 (虚拟的) 机器上。

在许多情况下,您唯一真正可行的替代方案是升级机器以包含更多内存优化应用程序以减少其内存占用。当您转向优化之路时,一个好的开始方法是使用内存转储 (heap dump) 分析程序来检测内存中的大额分配。

系列文章

  1. 8 种 Java 内存溢出之一:Java Heap Space
  2. 案例 1: 某财险承保系统内存泄漏问题
  3. 8 种 Java - 内存溢出之二 - GC overhead limit exceeded
  4. 案例 2: 某寿险公司核心系统 GC 开销超限问题分析
  5. 8 种 Java - 内存溢出之三 - Permgen space
  6. 案例 3: 某财险公司运行时的 Perm 区内存溢出分析
  7. 8 种 Java - 内存溢出之四 - Metaspace
  8. 8 种 Java - 内存溢出之五 - Unable to create new native thread
  9. 8 种 Java - 内存溢出六 - Out of swap space?
  10. 8 种 Java 内存溢出之七 - Requested array size exceeds VM limit
  11. 8 种 Java 内存溢出之八 - Kill process or sacrifice child

8 种 Java - 内存溢出六 - Out of swap space?
https://ewhisper.cn/posts/19073/
作者
东风微鸣
发布于
2017年11月3日
许可协议