Linux

我的容器的記憶體去哪兒了?

  • February 27, 2017

我有一個容器洩漏記憶體。或者至少,報告的記憶體消耗快速上升。如果我跑得最好,我會得到這個:

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 正在將我的程序的標準輸出寫入日誌文件。

引用自:https://serverfault.com/questions/833994