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。
swapoff -a dd if=/dev/zero of=swapfile bs=1024 count=655360 mkswap swapfile swapon swapfile SHELL |
现在,您应该回忆一下之前的内容,由于垃圾收集清除内存内容,一般来说,对于 Java 进程, 交换 (swapping) 是不受欢迎的。 在交换分配 (swapped allocations) 上运行垃圾收集算法会增加好几个数量级的 GC 暂停时间,所以在跳到这个简单解决方案的时候,你应该三思而后行。
如果您的应用程序部署在与需要竞争资源的“扰民恶邻”的 JVM 的旁边,那么您应该将服务隔离到独立的 (虚拟的) 机器上。
在许多情况下,您 唯一真正可行的替代方案是升级机器以包含更多内存 或优化应用程序以减少其内存占用 。当您转向优化之路时,一个好的开始方法是使用内存转储(heap dump) 分析程序来检测内存中的大额分配。