我快要疯了,想在我们的一个主机器上找到内存泄漏。它运行 CentOS,内核 2.6.18,x86-64。这个机器(实际上是 Xen 上的 VM)自大约 6 个月前创建以来一直运行良好,没有任何问题。它是为替换旧的物理机器而创建的,配置方式相同。VM 是一个 Web 服务器,只运行 Tomcat 和 Apache。它很稳定,没有问题,也没有内存泄漏。
大约两周前,我们遇到了一个问题,Xen 设置中的四台物理服务器中有两台重新启动了(出于某种原因)。我们过了一会儿就恢复了,没有遇到太多问题(我们不得不重新加载一个 MySQL 数据库,由于中断,该数据库在复制过程中丢失了一些记录)。
从那时起,这台虚拟机就出现了内存问题。我们拥有的其他虚拟机都没有出现问题,只有这台虚拟机出现了问题。内存使用量会增加,最高可达 200 MB/h,直到内存耗尽。它会消耗掉交换空间,然后 OOM 杀手会开始造成问题,直到我们重新启动虚拟机。
在尝试了其他操作(重新启动虚拟机、重新启动物理服务器、将虚拟机迁移到其他物理服务器)后,我使用 RPM 验证磁盘上的所有文件,以查找损坏情况。我在软件包中发现了几个文件,我不确定我们是否使用过,所以我重新安装了软件包,这样它们就又干净了。
这减缓了泄漏,但泄漏仍然存在。我们现在的泄漏速度为 10-50 MB/小时,但似乎在接近尾声时会加速。昨天,当服务器几乎处于空闲状态时,内存迅速攀升,不知何故在 12 小时内上升了 2.5 GB。
有趣的是,在运行 rpm 验证所有内容后,就在进程退出之前,它占用了几乎所有的可用物理内存,之后必须重新启动虚拟机。唯一的配置更改是将虚拟机的内存从 2GB 增加到 4GB,这样内存耗尽所需的时间更长,重新启动的次数也更少。
我尝试过跟踪内存。我们丢失的似乎是匿名页面,而且由于该框实际上并不使用其磁盘,所以我并不惊讶于我们丢失的页面没有磁盘支持。Tomcat/Java 有 2 GB 的虚拟内存,并且驻留内存约为 1 GB(最多分配 1.5 GB)。就像我之前说的,这是它已经使用了 6 个多月的配置,也是它之前的框在此之前使用过的配置。
事故发生前大约一周,我们的软件没有更新过,所以问题不在这里。我们重建了系统并进行了更新,但问题并没有解决。
我们尝试使用 yum 更新系统上的其他所有内容,但没有什么效果。唯一没有使用 yum 安装的软件是 Java(我已更新)和我们的软件(我已更新)。
我编写了一个小程序,通过计算 /proc 文件系统中的总数来跟踪虚拟机上每个进程的总虚拟大小、驻留大小和数据段大小。运行一天后,你可以看到 Apache 的虚拟大小随着负载上下波动,但驻留大小基本没有变化。Java 非常缓慢地增加,一整天大约增加 50mb,与我们预期的一致。然而,在此期间,我们损失了 500 多 MB 的内存。Top 没有显示任何使用比 Java 更多的内存的内容。我的程序发现服务器上的每个进程(Java 和 Apache 除外)在一天内的变化不超过几千字节。
基本上,有什么东西在消耗我们的内存,但我完全不知道是什么。我猜是内核,但即使内存使用率很高,内核的内存大小(/proc/vmstat 中的列表,我不记得了)也只有大约 200 兆字节。
至此,我们已准备好从头开始重建虚拟机。我想这就是最终的结果。
当发生这种情况时,如何追踪内存泄漏?我从未见过这样的内存泄漏(未显示在 top 中),但我的经验非常有限。有人可以建议我可以查看的内容或在这种情况下可以使用的工具吗?
答案1
VM 有可能被黑客入侵了吗?您用来监控进程和内存列表的工具是否来自已知良好的只读介质?您可能安装了隐藏漏洞进程的 rootkit。
答案2
我们在 Centos05 和相同内核上也遇到了类似的问题。内存不断增加,这是无法解释的。我们认为这可能与我们安装的某些库/程序有关。您安装了 Hdf5 吗?哪个版本?目前,这是我们的主要怀疑对象。Openmpi/mpich2 是我们的第一个怀疑对象,但是,它们似乎没问题。不过不确定。如果我没记错的话,这个问题也发生在以前的内核上。
答案3
我在 xen 重启时遇到了问题,在较新的内核上情况非常糟糕,我发现 1 个虚拟机在我从重启服务器移至另一台服务器时也导致其崩溃,所以我意识到这是其中一个客户机的问题。我使用了 Citrix xen,它使用 2.6.18 内核,并重建了客户机,并且一直很稳定,但现在从 citrix 移至普通 xen 2.6.18 内核,并再次重建了客户机,它仍然很好。后来我开始遇到另一个 xen 客户机的问题,但它没有摧毁主机,但确实导致客户机严重崩溃,以至于我无法进入控制台,只能将所有组件更新为不稳定版本。真是够奇怪的,它现在实际上很稳定 :)