打包檔案以及啟動java程式對Linux記憶體擠壓情況的研究

济南小老虎發表於2024-05-15

打包檔案以及啟動java程式對Linux記憶體擠壓情況的研究


TLDR

先說一下簡單結論

java 啟動. tar包打包都會佔用快取
並且這個快取不是算到對應的 程序pid裡面
算到的是核心層的快取檔案裡面

如果核心不是很快速的釋放快取
會導致free 的記憶體越來越少.
如果此時 java 的程序記憶體使用量較高
是有一定機率被OS進行OOM killer的

所以不能100%的計算記憶體使用
要留給 
1. OS需要的
2. 快取檔案需要的
3. 網路棧, 其他程序需要的記憶體

用到的工具

pgcacher
smem
free 

驗證

java伺服器啟動中的驗證
啟動之前:
      total        used        free      shared  buff/cache   available
Mem:  30875         628       29622         405         625       29474

然後使用pgcacher 檢視 
pgcacher -top -limit 10
Size           │ Pages       │ Cached Size    │ Cached Pages│ Percent
576.269M       │ 147527      │ 372.222M       │ 95290       │ 64.592

smem的結果為
[root@kylinv10sp3 /]# smem -k -w
Area                           Used      Cache   Noncache
firmware/hardware                 0          0          0
kernel image                      0          0          0
kernel dynamic memory        794.3M     405.7M     388.6M
userspace memory             467.5M     224.9M     242.6M
free memory                   28.9G      28.9G          0

執行一分鐘後, 部分資訊為:

| Name                             | Size           │ Pages       │ Cached Size    │ Cached Pages│ Percent |
java/x86_64-linux/jre/lib/rt.jar   | 62.528M        | 16008       | 46.849M        | 11994       | 74.925  |

可以看到有部分檔案已經開始進行進入快取了. 

使用pgcacher -pid $pid 的資訊
| Name  | Size           │ Pages       │ Cached Size    │ Cached Pages│ Percent |
|Sum    │ 1.419G         │ 372201      │ 565.765M       │ 145062      │ 38.974  |

需要說明. 
pgcacher 算出來的 應該算是kernel 的記憶體 而不是程序消耗的記憶體. 
這一塊可以透過 echo 3 >/proc/sys/vm/drop_caches 來進行驗證. 

另外發現啟動過程中 java 程序會佔用約 500MB的快取
echo 3 後會降低到 100MB左右. 

關於記憶體釋放

kill java 之前
buff/Cache
804
然後 smem 的結果為
Area                           Used      Cache   Noncache
firmware/hardware                 0          0          0
kernel image                      0          0          0
kernel dynamic memory        866.2M     444.2M     422.0M
userspace memory              14.9G     362.9M      14.6G
free memory                   14.4G      14.4G          0

kill之後
buff/Cache
803
但是 smem的結果為:
[root@kylinv10sp3 gscloud]# smem -w -k
Area                           Used      Cache   Noncache
firmware/hardware                 0          0          0
kernel image                      0          0          0
kernel dynamic memory        964.9M     576.3M     388.6M
userspace memory             471.0M     226.8M     244.2M
free memory                   28.8G      28.8G          0

可以看到 smem 的記憶體已經降低了
但是free 顯示的記憶體沒降低

程序雖然被殺死了, 但是 快取不會清理. 

關於 tar 時快取的使用

開始壓縮檔案之前
free的結果
buff/cache
806
smem -w -k 
Area                           Used      Cache   Noncache
firmware/hardware                 0          0          0
kernel image                      0          0          0
kernel dynamic memory        966.6M     579.6M     387.0M
userspace memory             471.8M     226.9M     244.9M
free memory                   28.7G      28.7G          0

壓縮100秒後, 檔案大約 1G左右時
buff/cache
2697
[root@kylinv10sp3 gscloud]# smem -w -k
Area                           Used      Cache   Noncache
firmware/hardware                 0          0          0
kernel image                      0          0          0
kernel dynamic memory          2.6G       2.2G     384.8M
userspace memory             473.9M     227.7M     246.2M
free memory                   27.1G      27.1G          0

發現 tar 會佔用1倍多的已壓縮檔案大小的快取
並且 不是在tar的快取裡面的

是全部的系統快取
使用量會激增. 

相關文章