記憶體那些事

2021-09-08 11:24:45 字數 3151 閱讀 3392

linux中的free -m可以檢視當前的記憶體使用情況

[yejianfeng@iz23fsd ~]$ free -m

total used free shared buffers cached

mem: 7869 7737 132 0 489 4419

-/+ buffers/cache: 2828 5040

swap: 0 0 0

這裡會讓人奇怪的就是為什麼除了used和free,還有個buffers,cached的使用。

buffer是系統把將要寫入磁碟的資料先存放起來,然後一次性寫入磁碟。cache則是將要從磁碟讀取的資料先快取起來,等待下次讀取或者一次性讀取。對於人來說,我們認為這一部分的快取是已經使用了的,但是對於作業系統來說,這一部分的記憶體是「沒有使用」的。因為這部分的記憶體隨時可以釋放。所以這部分意思是:

total: 總共有的記憶體

used: 已經使用的記憶體數(人的角度看的,既: 程序實際使用的記憶體+buffers+cached)

free: 空閒記憶體(人的角度看的)

shared: 程序共享記憶體

buffers: 作業系統預留的為程序io讀取使用的緩衝區

cached: 作業系統為最近開啟的檔案進行的快取

-/+ buffer: 作業系統角度看的實際使用的記憶體數

我們在使用top命令看程序的時候,會看到下面的幾個東西:

pid user pr ni virt res shr s %cpu %mem time+ command

2344 vagrant 20 0 98276 2020 1052 s 0.0 0.4 0:00.49 sshd

2345 vagrant 20 0 105m 1868 1488 s 0.0 0.4 0:00.08 bash

1136 nginx 20 0 45676 1740 440 s 0.0 0.4 0:00.00 nginx

1022 root 20 0 308m 1604 820 s 0.0 0.3 0:05.10 vboxservice

這裡會看到幾個屬性:

virt res shr

這三個值都是表示這個程序的記憶體使用狀況,其中的virt指的是程序使用的虛擬記憶體,res指的是程序使用的物理記憶體,shr指的是程序使用的共享記憶體。

打乙個形象的比喻,一列車從北京到上海,有1500公里,我們應該要鋪設1500公里的鐵軌。但是,我們想了個取巧的辦法,我們實際只需要三公里的鐵軌,當列車快行駛完成鐵軌的時候,我們把已經走過的鐵軌鋪設到列車前方,這樣,列車就可以使用3公里的鐵軌就進行行駛了。在這個例子中,虛擬記憶體就是代表1500公里,而物理記憶體就是代表3公里。我們乙個程序在作業系統中實際使用的物理記憶體會遠遠小於分配的虛擬記憶體。比如乙個php-fpm程序實際使用大概20-30m的物理記憶體,而你看他的虛擬記憶體,大概會有150m左右。

我們機器的記憶體是恆定的,那麼這些大出來的虛擬記憶體是存放在**的呢?當然是硬碟。對於計算機來說,處理資訊查詢會先在l1快取中找需要的資料,如果沒有,在l2快取中查詢,如果還沒有,在記憶體中查詢,如果還沒有,先去硬碟中的虛擬記憶體區域找,如果還沒有,再去硬碟中找,如果都沒有,就跳過這次處理(可能程式崩潰或者藍屏)。

引入虛擬記憶體技術的好處是程式不需要再管物理記憶體中哪塊空閒,哪塊有用了。這些全部交給作業系統來管理,再程式面前,就像是有一塊連續的,未使用的記憶體空間一樣。當程式啟動的時候,系統會為每個程式分配一定的記憶體空間。在32bit的機器上,這個記憶體空間的上限是4g(0x00000000 - 0xffffffff),而其中分為兩個部分,使用者態使用的記憶體,核心態使用的記憶體。其中3g(0x00000000 - 0xbfffffff)是使用者態可以使用的記憶體,而1g(0xc0000000 - 0xffffffff)是核心態使用的記憶體。所以在許多windows的x86機器上,安裝的記憶體條大小最多是4g的,因為安裝再大的記憶體,可以使用的記憶體大小也是有限制的。

[vagrant@localhost /]$ ulimit -a

core file size (blocks, -c) 0

data seg size (kbytes, -d) unlimited

scheduling priority (-e) 0

file size (blocks, -f) unlimited

pending signals (-i) 3528

max locked memory (kbytes, -l) 64

max memory size (kbytes, -m) unlimited

open files (-n) 1024

pipe size (512 bytes, -p) 8

posix message queues (bytes, -q) 819200

real-time priority (-r) 0

stack size (kbytes, -s) 10240

cpu time (seconds, -t) unlimited

max user processes (-u) 1024

virtual memory (kbytes, -v) unlimited

file locks (-x) unlimited

對於虛擬記憶體和物理記憶體,這裡其實最複雜的是他們的對映機制。這個機制是作業系統核心要實現的東東,這裡就不繼續看下去了。

很多程序可能需要載入動態庫,比如libc,而這些動態庫就可以預設存放到共享記憶體中,而不用每個程序都進行載入了。還有程序也可以存放資料到共享記憶體中,這樣他們的子程序就可以到共享記憶體中進行操作,比如php的shmop系列的命令就是操作共享記憶體的。

好了,這裡有個奇怪的現象,明明top中在shr中看到很多共享記憶體,為什麼free -m中的shared為0呢?--實際上free命令中的shared已經被廢棄了,沒有進行計算了。具體參考man

記憶體的那些事

堆 heap 為程式儲存的一塊記憶體區域,用來儲存那些在執行時才知道其存在與大小的資料 程式能夠從堆中分配記憶體給這些元素 在用完之後,應該釋放掉這些記憶體。堆中所有的的東西都是匿名的 不能按名字直接訪問只能通過指標間接的訪問 棧 stack 為程式儲存的一塊記憶體區域,用來儲存狀態資料,例如 過程...

c 記憶體對齊那些事

一.記憶體對齊介紹 目前的計算機系統中 cpu都是按照位元組進行讀取儲存的記憶體資料,訪問某乙個變數的時候 需要在特定的位址空間中訪問,此時就需要各種不同型別的變數在記憶體空間中按照一定的規則進行排放,而不是乙個接乙個的進行有序排放。所以現代編譯器中都會對記憶體進行自動的對齊。struct stru...

OC學習那些事 記憶體管理

1.範圍 任何繼承了nsobject的物件,對基本資料型別無效。2.原理 每個物件內部都儲存了乙個與之相關聯的整數,稱為 引用計數器。當使用alloc new或者copy 建立乙個物件的時,物件的引用計數器設定為1。給物件傳送一條 retain訊息 可以使引用 計數器 1。給物件傳送一條 relea...