我的服务器运行的是 liquidsoap+icecast 包和简单的网站 (httpd+mysqld)。没什么特别的。每天大约有 2000 多名访客,平均同时在线人数约为 50 人。
服务器有 8GB RAM。随着时间的推移,可用内存量不断减少,尽管服务器上没有启动任何新程序,也没有新用户。在某个时候它开始交换,服务器上的负载上升,并且变得无响应。通常我所做的只是重新启动服务器...
怎样才能检测出到底是什么泄漏了内存?我使用 top 来监视资源的使用情况,但据我所知,它没有任何帮助:
有什么方法可以找出哪些程序使用了那么多内存?或者哪些程序开始大量交换到磁盘?有没有办法在不重启服务器的情况下释放内存?
答案1
以批处理模式运行top
以定期报告内存大小可用于在出现问题时查看谁在使用内存。运行sar
在批处理模式下应该可以对内存使用情况和相关 I/O 进行一些良好的诊断。运行munin
以监视系统应该会为您提供一个图表,其中包含有关内存用途的详细信息。这可能会有很大帮助。
您可以使用 limits.conf 来限制程序的最大核心大小。正确设置后,这应该会终止任何泄漏内存的程序。这适用于 pam_limits 模块。也可以使用命令设置限制ulimits
。
您正在运行一些可能使用大量内存的程序。您可以查看以下一些内容。
- 运行在 Apache 下的编程不良的应用程序
apache2
可能会泄漏内存。发生这种情况时,您应该会看到内存大小增加。您可以调整 apache2,使其在使用一定次数后回收子进程,方法是将其设置MaxRequestsPerChild
为 100 左右。如果这解决了问题,那么您需要解决泄漏问题。我会先观察一下。 - MySQL 可能会尝试将数据加载到内存中。如果内存中有大量数据,这可能会导致一些抖动,但不会像您看到的那样严重。
- 如果您安装了大型
tmpfs
文件系统,则在使用文件时如果不删除,则可能会泄漏内存。大型长寿命文件也可能是一个问题。 - 如果问题发生在一天中的大约同一时间,则您可能有一个正在泄漏内存的预定程序。
- 如果您的程序分配了共享内存,但在退出前没有释放它,那么您将面临相对不可见的内存泄漏。如果共享内存被锁定在内存中,则可能会强制交换。可用的共享内存量通常相对有限。
- liquidsoap+icecast 捆绑包可能会遇到占用内存的缓冲问题。我没有使用过这种组合,所以不确定会出现什么问题。
正常内存使用情况:您不需要很多可用内存。如果您的系统已运行很长时间并且有大量可用内存,则说明出现了问题。每次读取或写入文件时,块都会进入缓冲区缓存。这会减少您的可用内存,这是一件好事。系统将保留足够的可用空间来启动一些程序,而无需在其他地方寻找内存。由于许多程序运行速度很快,因此当它们停止运行时,它们的内存将返回到可用池。
当您读取缓冲区缓存中的文件时,无需访问磁盘,读取操作将从缓冲区缓存中解析。写入使用类似的机制。如果您的系统需要内存,缓冲区缓存是首先使用的地方之一。大多数缓冲区可以立即释放。
如果出现内存泄漏,您将看到可用内存和缓冲区都开始缩小。这仍然不是一个严重的问题,因为泄漏的内存最终应该被移动到交换空间。您的系统仍将正常运行,直到您填满交换空间,并将剩余的可用空间耗尽到程序无法启动的程度。通常可能会使用少量的交换空间。
答案2
您可以使用此命令查看 RAM 使用率最高的 10 个应用程序:
ps -A --sort -rss -o comm,pmem | head -n 11
如果生成了许多子进程,有时此命令会对您有所帮助:
ps auxf
这样您就可以看到哪些进程属于一起。
答案3
就应用程序而言,实际上没有任何东西使用该内存。
您需要扣除代表页面缓存的“缓存”值,以便更好地了解程序使用方面的实际内存使用情况。
基本上,这是良好的内存管理,这也是您理想中的情况。
请参阅此处的链接以了解更多信息:http://www.linuxatemyram.com/
答案4
我其实不是这方面的专家,但 liquid soap+icecast 与多媒体有关。当系统空闲时,它会缓存和/或占用内存以备将来使用。如果流量在一天中的某个时间/一段时间内增加,那么它将开始交换。此时,如果请求(查看内容的用户)增加,则所需的资源将超过 8GB 的 RAM。