某些东西耗尽了所有内存(我怀疑某些应用程序内存泄漏)。如何检测到什么?


16

我有运行liquidsoap + icecast捆绑软件和简单网站(httpd + mysqld)的服务器。没什么特别的。每天大约2000+的访问者,平均同时在线的访问者约为50。

服务器有8GB RAM。随着时间的流逝,尽管服务器上没有启动任何新操作,也没有新用户,但可用内存量不断减少。在某个时候它开始交换,服务器上的负载增加并且变得无响应。通常我要做的就是重启服务器...

如何检测到底是什么导致内存泄漏?我使用top监视资源使用情况,但据我所知,它没有任何帮助:

在此处输入图片说明

有什么办法找出使用那么多内存的东西吗?还是什么开始大量交换到磁盘?有什么方法可以释放内存而无需重新启动服务器?


为什么不尝试重新启动某些服务(apache,liquidsoap)而不是服务器的任何原因?
jamespo 2011年

我最初对正常的内存使用情况做出了回应。我已经更新了一套工具,可以帮助您识别问题。
BillThor

@jamespo,实际上我尝试过,但是没有效果,所以重启是我所知道的唯一可以帮助的事情。
jayarjo 2011年

缓存的4027092k应该说明内存使用情况,不是吗?我目前正在其他地方解决类似的问题,到目前为止,我设法弄清楚可以使用以下参数来调节内存传输:vfs_cache_pressure vm.dirty_ratio vm.dirty_background_ratio这不是一个完整的修复程序,任何反馈都可以最受欢迎的。我希望这是正确的方向。

Answers:


16

可以top以批处理模式运行以定期报告内存大小,以查看发生异常情况时谁在使用内存。乳宁sar在批处理模式下应提供对内存的使用,以及相关的I / O一些很好的诊断。运行munin以监视系统应该为您提供一个图形,其中详细说明了正在使用的内存。这可能会有所帮助。

您可以使用limits.conf来限制程序的最大核心大小。正确设置,这将杀死所有正在泄漏内存的程序。这适用于pam_limits模块。限制也可以通过ulimits命令设置。

您正在运行一些程序,这些程序可能会占用大量内存。您可能会看到的一些东西包括。

  • 在下面运行的编程不良的应用程序apache2可能会泄漏内存。发生这种情况时,您应该看到内存大小增加。您可以通过将apache2设置MaxRequestsPerChild为100左右来调整apache2在一定次数的使用后回收儿童。如果这样可以解决问题,则需要解决泄漏。我先看。
  • MySQL可能会尝试将数据加载到内存中。如果您的内存中有大量数据,则可能会导致一些异常,但不应像您看到的那样剧烈。
  • 如果安装了大型tmpfs文件系统,则在使用时未删除文件的情况下可能会泄漏内存。大而寿命长的文件也可能是一个问题。
  • 如果问题是在一天的大约同一时间发生的,则您可能有一个计划的程序正在泄漏内存。
  • 如果您有一个分配共享内存的程序,但是在退出之前没有释放它,则将有相对不可见的内存泄漏。如果共享内存被锁定在内存中,则可能会强制交换。可用共享内存的数量通常相对有限。
  • Liquidsoap + icecast捆绑包可能会遇到使用内存的缓冲问题。我没有使用过这种组合,所以我不确定这种外观如何。

正常的内存使用情况:空闲内存并不是您想要的很多东西。如果您的系统已启动很长时间并且有很多可用内存,则可能是错误的。每次读取或写入文件时,这些块都会进入缓冲区缓存。这将减少您的可用内存,这是一件好事。系统将保留足够的可用空间来启动一些程序,而无需在其他地方寻找内存。由于许多程序快速运行,因此它们的内存将在停止运行时返回到空闲池。

当您读取缓冲区高速缓存中的文件时,不需要磁盘访问,并且可以从缓冲区高速缓存中解析读取。写入使用类似的机制。如果您的系统需要内存,则缓冲区高速缓存是使用的最早位置之一。大多数缓冲区可以立即释放。

如果发生内存泄漏,您将看到可用内存和缓冲区都开始减少。这仍然不是一个严重的问题,因为泄漏的内存最终应移至交换空间。在您填充交换空间并将剩余的可用空间减少到无法启动程序之前,您的系统仍然可以正常运行。通常可以使用少量的交换空间。


就我而言,这个问题有点奇怪。即使负载很大并且服务器交换频繁,但仍有大量可用内存(据我了解缓冲区和缓存后的了解)。top不会显示任何进程在不断消耗内存。但是负载增加了,服务器有时变得不可用了:| 感谢您的详细回复。
jayarjo 2011年

2
@jayarjo:Munin和sar应该帮助发现正在发生的事情。如果您有很多可用内存,则不应该进行交换。您可能有其他的I / O问题。 sar将有助于查明哪个分区具有I / O,并可能有助于发现问题。
BillThor 2011年

为MaxRequestsPerChild建议+1
jamespo 2011年

11

您可以使用此命令查看有关RAM使用率的前10个应用程序:

ps -A --sort -rss -o comm,pmem | head -n 11

有时,如果已生成许多子进程,此命令将为您提供帮助:

ps auxf

这样,您可以查看哪些进程属于同一类。


这些是方便的命令,谢谢,我会在将来为您提供注意。但是问题是,顶部总是有相同的过程(您可以在所附的屏幕截图中看到它们)-apache,mysql,liquidsoap,icecast。而且,即使服务器死于负载,它们也使用(或至少显示为使用)相同数量的内存(实际上可以忽略不计):
jayarjo 2011年

@jayarjo:进程数是否改变?您还有更多流程吗?它是物理服务器还是虚拟服务器?
Raffael Luthiger 2011年

我还没有注意到进程数量的任何变化。基本上,当我完成任务时,当服务器正在减少负载时,除了巨大的负载之外,我看到的图片与我在原始问题中附加的内容非常相似:服务器是物理的。
jayarjo 2011年

2
尝试获取有关“ vmstat”的更多信息(例如vmstat -s)。或者使用已经提到的工具“ sar”。您是否有基于RAM的文件系统?然后,也许“ iostat”也可以提供更多信息。
Raffael Luthiger 2011年

1
我一直在怀疑是否尝试检测内存泄漏时查看pstop输出中的“ pmem”(%MEM)字段是否正确:这是否仅是进程当前使用的物理内存的百分比?但是该进程的已用(包括泄漏)内存的其他部分可能会换出。也许“ size”或“ vsize”更适合于衡量一个进程的大小?例如,ps -A --sort -size -o comm,size | head -n 11ps -A --sort -vsize -o comm,vsize | head -n 11
imz –伊万·扎哈拉雅舒夫(Ivan Zakharyaschev)2012年

8

就应用程序而言,实际上并没有真正使用该内存。

您需要减去代表页面高速缓存的'cached'值,以便更好地了解程序使用情况下实际的内存使用量。

基本上,这是很好的内存管理,并且理想情况下这就是您想要的。

有关更多信息,请参见此处的链接:http : //www.linuxatemyram.com/


是的,找到了链接并了解了缓冲区和高速缓存,但是据我所读的内容,它们不能引起交换,可以吗?
jayarjo 2011年

@jayarjo我想了解那里发生了什么,我们需要统计数据才能证明问题所在。您提供的数字不会显示交换或大量实际内存使用情况。
马修·伊夫

1

我真的不是专业人士,但是肥皂+冰封与多媒体有关。当系统空闲时,它将缓存和/或占用内存以备将来使用。并且,如果流量在一天中的特定时间/一段时间内增加,则它将开始交换。此时,如果请求(用户查看内容)增加,则所需资源将超过8GB。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.