這是新公司有個同事提到的,我恰好是負責這一塊的,因而給他解答以下。數組
問題:ide
寫了一個簡單的測試程序,申請2G內存但不使用,理論上不使用的內存不會佔用系統的物理內存和swap。top顯示這個進程使用了2G swap,但整個系統只使用了1G swap。感受TOP顯示的swap信息徹底是忽悠。
top - 12:03:30 up 109 days, 4:14, 16 users, load average: 1.00, 1.02, 1.00
Tasks: 1 total, 0 running, 1 sleeping, 0 stopped, 0 zombie
Cpu(s): 9.2%us, 3.4%sy, 0.0%ni, 87.5%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
Mem: 12462160k total, 7966312k used, 4495848k free, 465772k buffers
Swap : 4192956k total, 1257252k used , 2935704k free, 5561148k cached
PID USER PR VIRT RES SHR S %CPU %MEM TIME+ SWAP DATA COMMAND
22051 zhouzm 15 2050m 388 320 S 0.0 0.0 0:00.00 2.0g 2.0g a.out測試
解答:spa
彙總區域顯示的Swap: 1257252k used是正確的,不過任務區域的SWAP 2.0g其實也不算是錯的,我以爲是表達的意義不同。top源代碼裏面,不像其它參數,SWAP不是直接讀取/proc/pid/stat文件數據的, 是這樣計算的:SWAP = VIRT - RES,依賴於VIRT和RES。其中,VIRT(虛擬內存)是分配和釋放內存時會變化的,而RES(即RAM)是使用的時候隨着頁面交換變化的。在剛分配大量內存但尚未使用的時候,VIRT明顯變大但RES沒有明顯變化,致使SWAP變得出奇的大。
如下是我分配和使用2G大的數組,使用top捕捉到的變化過程:
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ SWAP COMMAND
before malloc 2G memory
4415 liangry 16 0 2404 248 192 S 0.0 0.0 0:00.00 2156 test_top_swap
after malloc 2G memory
4415 liangry 16 0 2050m 292 228 S 0.0 0.0 0:00.00 2.0g test_top_swap
start using the array
4415 liangry 25 0 2050m 733m 260 R 99.9 73.3 0:03.57 1.3g test_top_swap
end of assignment
4415 liangry 18 0 2050m 893m 84 R 24.3 89.3 0:11.19 1.1g test_top_swaporm
測試代碼:進程
#include <stdio.h> #include <stdlib.h> #include <string.h> int main(void) { sleep(15); long size = (long) 1024 * 1024 * 1024 * 2; char *s = (char *) malloc(sizeof(char) * size); sleep(15); long offset = 0; printf("starting.../n"); while ( offset < size ) { strcpy(s + offset, "hello"); offset += strlen("hello"); } printf("sleeping.../n"); sleep(99999); free(s); return 0; }