http 守护进程例如:
我用
ps aux|grep httpd|grep -v grep
:
USER PID RSS COMMAND
root 14347 3220 /usr/sbin/httpd
apache 14348 2400 /usr/sbin/httpd
apache 14349 2400 /usr/sbin/httpd
apache 14350 2400 /usr/sbin/httpd
我可以简单地累加RSS字段来获得[httpd]的总内存使用量。 3220+2400+2400+2400 = 10420
但我知道,子进程具有共享内存。这里有一些冗余计算。实际上总内存使用量可能小于10420。
我的问题是如何获取实际的内存使用情况。
如果您需要获取实际的内存使用情况,您需要在像 Valgrind 这样的分析器中运行它。
参考
http://kratos-wiki.cimne.upc.edu/index.php/Checking_memory_use_with_Valgrind
我在 Chrome 中使用了以下命令:
ps aux | grep chrome | grep -v grep | awk '{s+=$5} END {print s}'
请注意,$5 实际上可能会有所不同,具体取决于
ps aux
实际显示其输出的方式。这对您可能有用也可能没用,并且还会显示总使用量(以字节为单位)。
我也在寻找这个答案。 我已经找到了一个有效的。 那就是在 Docker 这样的容器中运行服务。然后使用
docker container stats $containerid
示例:
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
329f402b9f2e test-apache2-1 0.15% 2.677GiB / 31.01GiB 8.63% 395MB / 159MB 77.9MB / 819kB 21
我不确定容器的哪个功能允许这样做。是cgroup吗?是命名空间吗? 有没有一种轻量级的方法可以测量多个进程的内存,而不需要像 Docker 或 LXC 这样的东西?
我确实知道的一件事是这里的数字是准确的。或者至少比将 ps 或 top 的所有内存加在一起更准确。
有几种方法可以完成您在这里提出的要求。一种涉及解析
procfs
,它不需要“root”权限,另一种是使用 Taskstats(一个 Netlink 接口),它需要“root”权限。
如果您可以使用 Generic Netlink 套接字获得 root 权限,那么到目前为止在开销方面是最佳的。
我有一个使用第一个解析解决方案的工作解决方案
procfs
:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os
import sys
import time
class ShMemMonitorProcess(object):
def __init__(self, ppid):
self.ppid = ppid
# Create a Sub-Class for Thread module
self.memory = {'kB':1024, 'mB':1024*1024, 'gB':1024*1024*1024}
self.scrape_procfs
def calculate_memory(self, vmrss):
memory, size = vmrss.split()
return int(memory) * self.memory[size]
@property
def scrape_procfs(self):
rss = 0
child_ps = dict()
start = time.time()
while (time.time() - start) < 100:
for pid in filter(lambda p: p.isdigit(), os.listdir('/proc')):
try:
# open /proc/PID/status but catch as some can be ephemeral
with open('/proc/{}/status'.format(pid)) as fh:
ppid = [i for i in fh.readlines() if i.startswith('PPid')]
if not ppid:
continue
ppid = ppid[0].split('\t')[1].strip('\n')
if ppid == self.ppid:
with open('/proc/{}/status'.format(pid)) as fh:
vmrss = fh.readlines()
vmrss = [i for i in vmrss if i.startswith('VmRSS')]
if not vmrss:
continue
vmrss = vmrss[0].split('\t')[1].strip('\n')
ps_rss = self.calculate_memory(vmrss)
if not child_ps.get(pid):
with open('/proc/{}/comm'.format(pid)) as fh:
comm = fh.readlines()
print('Found Child Process {}!'.format(pid))
print(comm)
print('Adding Process to Hash...')
child_ps[pid] = ps_rss
rss += ps_rss
time.sleep(1)
else:
# re-calculate process memory
print('Process was already found running...')
print('Re-calculating memory usage...')
previous_rss_used = child_ps[pid]
if previous_rss_used > ps_rss:
memory_adj = previous_rss_used - ps_rss
rss -= memory_adj
elif previous_rss_used <= ps_rss:
memory_adj = ps_rss - previous_rss_used
rss += memory_adj
child_ps[pid] = ps_rss
print('Bytes....{}'.format(rss))
except FileNotFoundError:
continue
if __name__ == '__main__':
# Pass the Process ID through STDIN on calling
pid = sys.argv[1]
shmem = ShMemMonitorProcess(pid)
然后只需使用您要查找 RSS 总数的组的“父级”进程的 PID 来调用此函数即可。
python ./Find_RSS.py 1234
Found Child Process 12541!
22:54:40 [12/222]
['Privileged Cont\n']
Adding Process to Hash...
Bytes....202661888
Found Child Process 12606!
['WebExtensions\n']
Adding Process to Hash...
Bytes....667672576
Found Child Process 12666!
['Utility Process\n']
Adding Process to Hash...
Bytes....709660672
Found Child Process 14803!
['RDD Process\n']