【Java内存溢出】系列(6/8): Out of swap space?

本篇是Java内存溢出系列第6小篇。

1.OutOfMemoryError之Java heap space

2.OutOfMemoryError之GC overhead limit exceeded

3.OutOfMemoryError之Permgen space

4.OutOfMemoryError之Metaspace

5.OutOfMemoryError之Unable to create new native thread

6.OutOfMemoryError之Out of swap space?

7.OutOfMemoryError之Requested array size exceeds VM limit

8.OutOfMemoryError之Kill process or sacrifice child

JVM启动参数指定了最大内存限制。如 -Xmx 以及相关的其他启动参数. 假若JVM使用的内存总量超过可用的物理内存, 操作系统就会用到虚拟内存。

错误信息 java.lang.OutOfMemoryError: Out of swap space? 表明, 交换空间(swap space,虚拟内存) 不足,是由于物理内存和交换空间都不足所以导致内存分配失败。

原因分析

如果 native heap 内存耗尽, 内存分配时, JVM 就会抛出 java.lang.OutOfmemoryError: Out of swap space? 错误消息, 这个消息告诉用户, 请求分配内存的操作失败了。

Java进程使用了虚拟内存才会发生这个错误。 对 Java的垃圾收集 来说这是很难应付的场景。即使现代的 GC算法 很先进, 但虚拟内存交换引发的系统延迟, 会让 GC暂停时间 膨胀到令人难以容忍的地步。

通常是操作系统层面的原因导致 java.lang.OutOfMemoryError: Out of swap space? 问题, 例如:

  • 操作系统的交换空间太小。
  • 机器上的某个进程耗光了所有的内存资源。

当然也可能是应用程序的本地内存泄漏(native leak)引起的, 例如, 某个程序/库不断地申请本地内存,却不进行释放。

解决方案

这个问题有多种解决办法。

第一种, 也是最简单的方法, 增加虚拟内存(swap space) 的大小. 各操作系统的设置方法不太一样, 比如Linux,可以使用下面的命令设置:

swapoff -a

dd if=/dev/zero of=swapfile bs=1024 count=655360

mkswap swapfile

swapon swapfile

其中创建了一个大小为 640MB 的 swapfile(交换文件) 并启用该文件。

因为垃圾收集器需要清理整个内存空间, 所以虚拟内存对 Java GC 来说是难以忍受的。存在内存交换时, 执行 垃圾收集 的 暂停时间 会增加上百倍,甚至更多, 所以最好不要增加虚拟内存。

如果程序允许环境还受到 “坏邻居效应” 的干扰, 那么JVM还要和其他程序竞争计算资源, 提高性能的办法就是单独部署到专用的服务器/虚拟机中。

大多数时候, 我们唯一能做的就是升级服务器配置, 增加物理机的内存。当然也可以进行程序优化, 降低内存空间的使用量, 通过堆转储分析器可以检测到哪些方法/代码分配了大量的内存。

本文是全系列中第6 / 8篇:java内存溢出系列

本站大部分下载资源收集于网络,只做学习和交流使用,版权归原作者所有,若为付费资源,请在下载后24小时之内自觉删除,若作商业用途,请到原网站购买,由于未及时购买和付费发生的侵权行为,与本站无关。本站发布的内容若侵犯到您的权益,请联系本站删除,我们将及时处理!