我有一个容器泄漏内存。或者至少,报告的内存消耗快速上升。如果我跑得最好,我会得到这个:
top - 16:56:51 up 6 days, 17:25, 0 users, load average: 0.16, 0.27, 0.31
Tasks: 4 total, 1 running, 3 sleeping, 0 stopped, 0 zombie
%Cpu(s): 1.3 us, 0.7 sy, 0.0 ni, 98.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem: 7676380 total, 4089380 used, 3587000 free, 675164 buffers
KiB Swap: 0 total, 0 used, 0 free. 2586496 cached Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1 root 20 0 46924 15196 6456 S 0.0 0.2 0:15.54 supervisord
8 root 20 0 3526084 47976 29660 S 0.0 0.6 0:59.15 dotnet
568 root 20 0 20364 3332 2728 S 0.0 0.0 0:00.09 bash
2800 root 20 0 21956 2420 2032 R 0.0 0.0 0:00.00 top
我现在报出来的数字是90M,不算加起来。我很确定/sys/fs/cgroup/memory/memory.usage_in_bytes
报告的内容是:
> cd /sys/fs/cgroup/memory/
> cat cgroup.procs
1
8
568
2494
> cat memory.usage_in_bytes
92282880
> pmap -p 1 | tail -n 1
total 46924K
> pmap -p 8 | tail -n 1
total 3599848K
> pmap -p 568 | tail -n 1
total 20364K
> ps 2494
PID TTY STAT TIME COMMAND
在我看来,这里有大量的内存“丢失”......如果我memory.usage_in_bytes
在这段时间里再次猫,我一直在输入这个:
> cat memory.usage_in_bytes
112291840
> pmap -p 1 | tail -n 1
total 46924K
> pmap -p 8 | tail -n 1
total 3452320K
> pmap -p 568 | tail -n 1
total 20368K
显然没有什么可以解释这种内存使用情况。如果我看一下,memory.stat
我会看到:
# cat memory.stat
cache 89698304
rss 30699520
rss_huge 0
mapped_file 1552384
writeback 0
pgpgin 102007
pgpgout 72613
pgfault 115021
pgmajfault 8
inactive_anon 1519616
active_anon 30789632
inactive_file 417792
active_file 87654400
unevictable 4096
hierarchical_memory_limit 18446744073709551615
total_cache 89698304
total_rss 30699520
total_rss_huge 0
total_mapped_file 1552384
total_writeback 0
total_pgpgin 102007
total_pgpgout 72613
total_pgfault 115021
total_pgmajfault 8
total_inactive_anon 1519616
total_active_anon 30789632
total_inactive_file 417792
total_active_file 87654400
total_unevictable 4096
片刻之后:
# cat memory.stat
cache 89972736
rss 30777344
rss_huge 0
mapped_file 1552384
writeback 0
pgpgin 102316
pgpgout 72836
pgfault 115674
pgmajfault 8
inactive_anon 1519616
active_anon 30867456
inactive_file 417792
active_file 87928832
unevictable 4096
hierarchical_memory_limit 18446744073709551615
total_cache 89972736
total_rss 30777344
total_rss_huge 0
total_mapped_file 1552384
total_writeback 0
total_pgpgin 102316
total_pgpgout 72836
total_pgfault 115674
total_pgmajfault 8
total_inactive_anon 1519616
total_active_anon 30867456
total_inactive_file 417792
total_active_file 87928832
total_unevictable 4096
但我会说实话;我真的不知道我在看什么。我又怀疑地看着active_file
;我真的不知道我在看什么。
一些注释和观察:
- 容器由 Kubernetes 调度。
- 该程序将大量数据写入标准输出。
- 将写入控制台的数据量减少到接近零可以解决报告的内存泄漏问题。
- 部署一个只向标准输出写入大量数据的程序似乎并没有表现出相同的内存泄漏(!)
所以!我应该如何去寻找这些内存被消耗的地方?有什么对任何人来说显而易见的东西——也许有什么东西在盯着我看,或者我没有看我应该看到的东西?
谢谢!
简而言之;
memory.usage
包括磁盘缓存。我应该测量(memory.usage
-memory.cache
)。问题(和感知到的内存泄漏)是 supervisord 正在将我的程序的标准输出写入日志文件。