我猜想存在一些内存泄漏,并且内存未被释放。 是否有一些好方法可以找出哪个进程以及为什么泄漏了内存?
唯一的临时解决方案是重启服务器。但几天后内存使用量不断增加,然后服务器速度变慢了很多,我不得不再次重启。
例如检查free -m
:
total used free shared buffers cached
Mem: 2005 1989 15 0 2 126
-/+ buffers/cache: 1861 144
Swap: 2004 1494 510
问题是这种使用情况并没有太大变化。并且这种内存使用情况要么保持这种冻结状态,要么变得越来越大,但不会减少。
有谁知道有什么好的做法可以查明内存泄漏的原因?
按已用内存排序的顶部显示以下内容:
top - 16:58:40 up 6:00, 1 user, load average: 0.10, 0.08, 0.07
Tasks: 136 total, 1 running, 135 sleeping, 0 stopped, 0 zombie
Cpu(s): 26.2%us, 1.0%sy, 0.0%ni, 72.8%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
Mem: 2053476k total, 2036380k used, 17096k free, 39272k buffers
Swap: 2053112k total, 13348k used, 2039764k free, 924372k cached
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1529 oerp 20 0 919m 419m 8100 S 19.9 20.9 17:44.49 python
1768 postgres 20 0 342m 161m 137m S 0.0 8.1 0:27.28 postgres
1775 postgres 20 0 334m 155m 137m S 0.0 7.8 0:14.05 postgres
1751 postgres 20 0 333m 152m 138m S 0.0 7.6 0:26.56 postgres
1779 postgres 20 0 330m 150m 136m S 0.0 7.5 0:13.73 postgres
1758 postgres 20 0 329m 149m 137m S 0.0 7.5 0:19.89 postgres
1742 postgres 20 0 330m 149m 137m S 0.0 7.5 0:10.19 postgres
1769 postgres 20 0 329m 149m 138m S 0.0 7.4 0:55.47 postgres
1760 postgres 20 0 329m 149m 137m S 0.0 7.4 0:16.52 postgres
1772 postgres 20 0 328m 148m 136m S 0.0 7.4 0:18.93 postgres
1764 postgres 20 0 328m 148m 137m S 0.0 7.4 0:17.72 postgres
1759 postgres 20 0 329m 148m 136m S 0.0 7.4 0:21.15 postgres
1757 postgres 20 0 330m 148m 136m S 5.6 7.4 0:17.73 postgres
1766 postgres 20 0 327m 148m 138m S 0.3 7.4 0:25.07 postgres
1762 postgres 20 0 328m 148m 136m S 0.0 7.4 0:17.91 postgres
1776 postgres 20 0 329m 147m 137m S 0.0 7.4 0:21.30 postgres
1770 postgres 20 0 328m 147m 136m S 0.0 7.4 0:16.01 postgres
很明显,Python 和 PostgreSQL 占用了所有的内存,但我如何才能找出没有释放任何内存的原因(Python 和 PostgreSQl 执行了许多不同的操作)?
使用ps aux
:
此过程使用大部分内存:
oerp 1529 4.9 20.9 916984 429332 ? Sl 10:58 17:55 /opt/odoo/venv/bin/python /opt/odoo/odoo/openerp-server --config=/etc/odoo-server.conf --no-database-list
但如果你把所有这些过程结合起来(有很多这样的过程)
postgres 1742 0.0 7.4 338268 153140 ? Ss 10:59 0:10 postgres: oerp nodbaltic [local] idle
那么它就占据了内存的最大部分。
postgresql 有许多空闲进程占用如此大量的内存,这正常吗?
cat /proc/meminfo
:
MemTotal: 2053476 kB
MemFree: 20312 kB
Buffers: 38944 kB
Cached: 926480 kB
SwapCached: 1196 kB
Active: 1431788 kB
Inactive: 490424 kB
Active(anon): 824712 kB
Inactive(anon): 276456 kB
Active(file): 607076 kB
Inactive(file): 213968 kB
Unevictable: 3884 kB
Mlocked: 3884 kB
SwapTotal: 2053112 kB
SwapFree: 2039340 kB
Dirty: 4144 kB
Writeback: 0 kB
AnonPages: 959108 kB
Mapped: 164144 kB
Shmem: 142332 kB
Slab: 58796 kB
SReclaimable: 38440 kB
SUnreclaim: 20356 kB
KernelStack: 1728 kB
PageTables: 28340 kB
NFS_Unstable: 0 kB
Bounce: 0 kB
WritebackTmp: 0 kB
CommitLimit: 3079848 kB
Committed_AS: 2131992 kB
VmallocTotal: 34359738367 kB
VmallocUsed: 281432 kB
VmallocChunk: 34359446164 kB
HardwareCorrupted: 0 kB
HugePages_Total: 0
HugePages_Free: 0
HugePages_Rsvd: 0
HugePages_Surp: 0
Hugepagesize: 2048 kB
DirectMap4k: 10240 kB
DirectMap2M: 2086912 kB
PS 哦,如果有什么区别的话,服务器正在虚拟机上运行。
答案1
该top
命令将显示当前正在运行的进程及其内存使用情况。该RES
列报告进程实际使用的内存。按Shift+M按该列排序。按Q按钮再次退出屏幕。
答案2
有几种方法可以找出哪些进程正在运行并使用内存。
Top 已经提到过了,但我更喜欢使用 atop 或 htop。您可以从您的存储库安装它们(yum install atop 或 apt-get install atop),它可以更好、更全面地概述服务器上发生的所有事情。您甚至可以配置 atop 每隔 x 分钟记录一次所有内容,这有助于调试您的问题。
也可以通过输入以下命令来检查当前正在运行的内容和使用的资源
ps 仿制品
PS 命令为您提供所有当前正在运行的进程的快照。其中有一列是 CPU 和 MEM 使用情况。
此外,仅使用 free -m 来调试内存问题可能会产生误导。最好检查一下:
猫/proc/meminfo
或者使用我提到的工具,如 atop 或 htop,因为它们可以更好地了解内存使用情况(缓存和缓冲区保留的内存)
此外,发布 ps faux 或 top/atop/htop 的结果将有助于我们更好地帮助您解决问题。
答案3
将内存中的所有数据移动到磁盘,清除物理内存:
sudo /bin/syncfree pagecache, dentries and inodes
sudo bash -c "echo 3 > /proc/sys/vm/drop_caches"
确保有足够的物理内存来存储整个交换空间,然后通过运行以下两个命令将交换的数据移回可用 RAM:
$ free -m
total used free shared buffers cached
Mem: 2048 884 1163 0 0 42
-/+ buffers/cache: 842 1205
Swap: 996 996 0
sudo /sbin/swapoff -a && sudo /sbin/swapon -a
这会将交换的项目移动到物理内存,禁用并重新启用交换。