內(nèi)存是計(jì)算機(jī)系統(tǒng)最重要的資源之一,當(dāng)操作系統(tǒng)內(nèi)存不足時(shí),進(jìn)程申請(qǐng)內(nèi)存將會(huì)失敗,從而導(dǎo)致其運(yùn)行異常或者崩潰。
Linux 內(nèi)核提供swap機(jī)制來(lái)解決內(nèi)存不足的情況,其原理是:
當(dāng)系統(tǒng)內(nèi)存不足時(shí),內(nèi)核會(huì)將進(jìn)程不常用的內(nèi)存交換(寫(xiě)入)到磁盤(pán)中,然后將這些內(nèi)存歸還給系統(tǒng),系統(tǒng)可以將這些內(nèi)存繼續(xù)分配給其他需要使用內(nèi)存的進(jìn)程。
通過(guò) swap 機(jī)制,系統(tǒng)可以將內(nèi)存分配給需求更迫切的進(jìn)程。但由于 swap 機(jī)制需要進(jìn)行 I/O 操作,所以一定程度上會(huì)影響系統(tǒng)性能。那么是否存在一種能夠節(jié)省內(nèi)存,而且對(duì)性能影響較少的機(jī)制呢?
在 Linux-3.14 引入了一種名為zRAM的技術(shù),zRAM 的原理是:將進(jìn)程不常用的內(nèi)存壓縮存儲(chǔ),從而達(dá)到節(jié)省內(nèi)存的使用。如下圖所示:
zRAM 機(jī)制建立在 swap 機(jī)制之上,swap 機(jī)制是將進(jìn)程不常用的內(nèi)存交換到磁盤(pán)中,而 zRAM 機(jī)制是將進(jìn)程不常用的內(nèi)存壓縮存儲(chǔ)在內(nèi)存某個(gè)區(qū)域。所以 zRAM 機(jī)制并不會(huì)發(fā)生 I/O 操作,從而避免因 I/O 操作導(dǎo)致的性能下降。
zRAM原理
由于 zRAM 機(jī)制是建立在 swap 機(jī)制之上,而 swap 機(jī)制需要配置文件系統(tǒng)或塊設(shè)備來(lái)完成的。所以 zRAM 虛擬一個(gè)塊設(shè)備,當(dāng)系統(tǒng)內(nèi)存不足時(shí),swap 機(jī)制將內(nèi)存寫(xiě)入到這個(gè)虛擬的塊設(shè)備中。也就是說(shuō),zRAM 機(jī)制本質(zhì)上只是一個(gè)虛擬塊設(shè)備。
zRAM 的原理如下圖所示:
從上圖可以看出,在開(kāi)啟了 zRAM 機(jī)制的情況下,當(dāng)系統(tǒng)內(nèi)存不足時(shí),內(nèi)核會(huì)進(jìn)行如下操作:
通過(guò) swap 機(jī)制從系統(tǒng)中查找一些進(jìn)程不常用的內(nèi)存。
將這些不常用的內(nèi)存交換到 zRAM 塊設(shè)備中,而 zRAM 塊設(shè)備首先會(huì)對(duì)這些不常用的內(nèi)存進(jìn)行壓縮,然后存儲(chǔ)起來(lái)。
把不常用的內(nèi)存壓縮存儲(chǔ)到 zRAM 塊設(shè)備后,swap 機(jī)制會(huì)把這些不常用的內(nèi)存歸還給內(nèi)核。
當(dāng)進(jìn)程訪問(wèn)到這些被交換到 zRAM 塊設(shè)備的內(nèi)存時(shí),swap 機(jī)制將會(huì)通過(guò) zRAM 塊設(shè)備解壓這些內(nèi)存,并且重新建立與進(jìn)程的地址映射關(guān)系。
啟用zRAM
1. 創(chuàng)建 zRAM 塊設(shè)備
要啟用 zRAM,首先需要?jiǎng)?chuàng)建 zRAM 塊設(shè)備。要?jiǎng)?chuàng)建 zRAM 塊設(shè)備,可以使用以下命令:
modprobezramnum_devices=1
num_devices參數(shù)可以指定創(chuàng)建 zRAM 塊設(shè)備的個(gè)數(shù),上面命令創(chuàng)建了一個(gè) zRAM 塊設(shè)備,可以通過(guò)路徑/dev/zram0來(lái)訪問(wèn)這個(gè)塊設(shè)備。
2. 設(shè)置 zRAM 塊設(shè)備的大小
創(chuàng)建完 zRAM 塊設(shè)備后,可以通過(guò)以下命令來(lái)設(shè)置其空間大小:
echo512M>/sys/block/zram0/disksize
上面命令設(shè)置了zram0的大小為 512MB,也就是說(shuō),zram0能夠存儲(chǔ) 512MB 壓縮后的數(shù)據(jù)。
3. 壓縮算法選擇
zRAM 機(jī)制支持多種壓縮算法,不同的壓縮算法有不同的壓縮比率和壓縮速度,用戶(hù)可以按照自身的需求來(lái)選擇不同的壓縮算法。
要更改 zRAM 的壓縮算法,可以使用下面命令:
echolzo>/sys/block/zram0/comp_algorithm
上面命令將 zRAM 的壓縮算法更改為lzo,我們也可以通過(guò)下面命令來(lái)查看內(nèi)核支持哪些壓縮算法:
cat/sys/block/zram0/comp_algorithm lzo[lz4]
從上面命令的輸出可知,內(nèi)核支持lzo和lz4兩種壓縮算法。
4. 將 swap 交換設(shè)備設(shè)置為 zRAM
要將 swap 的交換設(shè)備設(shè)置為 zRAM 塊設(shè)備,可以使用以下命令:
mkswap/dev/zram0
當(dāng)執(zhí)行完上面這條命令后,內(nèi)核將會(huì)使用zram0作為 swap 的交換設(shè)備。
zRAM實(shí)現(xiàn)
zRAM 塊設(shè)備驅(qū)動(dòng)的實(shí)現(xiàn)代碼主要在drivers/block/zram/zram_drv.c文件中,下面我們主要圍繞此文件進(jìn)行分析。
本文并不會(huì)介紹塊設(shè)備驅(qū)動(dòng)的編寫(xiě)流程,只會(huì)分析 swap 機(jī)制在進(jìn)行內(nèi)存交換時(shí),與 zRAM 塊設(shè)備驅(qū)動(dòng)的交互。
壓縮內(nèi)存
當(dāng)系統(tǒng)內(nèi)存不足時(shí),內(nèi)核將會(huì)觸發(fā)swap機(jī)制。swap 機(jī)制首先會(huì)從系統(tǒng)中選擇一些進(jìn)程不常用內(nèi)存,然后將這些不常用的內(nèi)存交換到zRAM塊設(shè)備中(使用 zRAM 塊設(shè)備作為交換設(shè)備的情況下)。
當(dāng) swap 機(jī)制將不常用的內(nèi)存交換到 zRAM 塊設(shè)備時(shí),會(huì)調(diào)用zram_make_request()函數(shù)處理請(qǐng)求。而zram_make_request()最終會(huì)通過(guò)調(diào)用zram_bvec_write()函數(shù)來(lái)壓縮內(nèi)存,調(diào)用鏈如下:
zram_make_request() ->__zram_make_request() ->zram_bvec_rw() ->zram_bvec_write()
我們來(lái)分析一下zram_bvec_write()函數(shù)的實(shí)現(xiàn),其代碼如下:
staticint zram_bvec_write(structzram*zram,structbio_vec*bvec,u32index,intoffset) { ... //1.獲取需要進(jìn)行壓縮的內(nèi)存 page=bvec->bv_page; ... user_mem=kmap_atomic(page); uncmem=user_mem; ... //2.對(duì)內(nèi)存進(jìn)行壓縮 ret=zcomp_compress(zram->comp,zstrm,uncmem,&clen); ... //3.獲取壓縮后的數(shù)據(jù) src=zstrm->buffer; ... //4.申請(qǐng)一個(gè)內(nèi)存塊保存壓縮后的數(shù)據(jù) handle=zs_malloc(meta->mem_pool,clen); ... cmem=zs_map_object(meta->mem_pool,handle,ZS_MM_WO); //5.將壓縮后的數(shù)據(jù)保存到新申請(qǐng)的內(nèi)存塊中 memcpy(cmem,src,clen); ... //6.將壓縮后的數(shù)據(jù)登記到zRAM塊設(shè)備的表格中 meta->table[index].handle=handle; ... returnret; }
為了簡(jiǎn)化分析過(guò)程,我們對(duì)代碼進(jìn)行精簡(jiǎn)。從上面的代碼可以看出,zRAM 機(jī)制對(duì)內(nèi)存進(jìn)行壓縮的步驟如下:
獲取需要進(jìn)行壓縮的內(nèi)存,需要進(jìn)行壓縮的內(nèi)存由 swap 機(jī)制提供。
通過(guò)zcomp_compress()函數(shù)對(duì)內(nèi)存進(jìn)行壓縮,src指針指向壓縮后的內(nèi)存地址。
通過(guò)zs_malloc()和zs_map_object()函數(shù)申請(qǐng)一塊新的內(nèi)存塊,大小為壓縮后數(shù)據(jù)的大小。
將壓縮后的數(shù)據(jù)復(fù)制到新申請(qǐng)的內(nèi)存塊中。
將壓縮后的數(shù)據(jù)記錄到zRAM塊設(shè)備的表格中。
由于 zRAM 塊設(shè)備是建立在內(nèi)存中的虛擬塊設(shè)備,所以其并沒(méi)有真實(shí)塊設(shè)備的特性。真實(shí)塊設(shè)備會(huì)將存儲(chǔ)空間劃分成一個(gè)個(gè)塊,而zram_bvec_write()函數(shù)的index參數(shù)就是數(shù)據(jù)塊的編號(hào)。此參數(shù)有 swap 機(jī)制提供,所以 zRAM 塊設(shè)備驅(qū)動(dòng)通過(guò) index 參數(shù)作為原始內(nèi)存數(shù)據(jù)的編號(hào)。
一圖勝千言:
zRAM驅(qū)動(dòng)有個(gè)數(shù)據(jù)塊表,用來(lái)記錄原始內(nèi)存數(shù)據(jù)對(duì)應(yīng)的壓縮數(shù)據(jù),此表的索引就是數(shù)據(jù)塊的編號(hào)。swap 機(jī)制會(huì)維護(hù)此表格的使用情況,如哪個(gè)塊是空閑的,哪個(gè)塊被占用等。
當(dāng)內(nèi)存頁(yè)被壓縮后,swap 機(jī)制將會(huì)把原來(lái)的內(nèi)存頁(yè)釋放掉,并且把所有映射到此內(nèi)存頁(yè)的進(jìn)程解除映射,細(xì)節(jié)可以參考 swap 機(jī)制相關(guān)的資料。
審核編輯:劉清
-
Linux系統(tǒng)
+關(guān)注
關(guān)注
4文章
603瀏覽量
28292 -
SWAP
+關(guān)注
關(guān)注
0文章
51瀏覽量
13143 -
zram
+關(guān)注
關(guān)注
0文章
3瀏覽量
95
原文標(biāo)題:一文讀懂|zRAM 內(nèi)存壓縮機(jī)制
文章出處:【微信號(hào):LinuxHub,微信公眾號(hào):Linux愛(ài)好者】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
壓縮機(jī)油的特征及應(yīng)用
嵌入式系統(tǒng)中的內(nèi)存壓縮技術(shù)

什么是制冷壓縮機(jī),制冷壓縮機(jī)的工作原理
肖特推出了電動(dòng)壓縮機(jī)標(biāo)準(zhǔn)的壓縮機(jī)端子系列產(chǎn)品
半導(dǎo)體制冷和壓縮機(jī)制冷哪個(gè)好
滾動(dòng)轉(zhuǎn)子式壓縮機(jī)優(yōu)點(diǎn)_滾動(dòng)轉(zhuǎn)子式壓縮機(jī)的缺點(diǎn)

多滑片式壓縮機(jī)結(jié)構(gòu)圖_多滑片式壓縮機(jī)的特點(diǎn)
容積型壓縮機(jī)分類(lèi)_容積型壓縮機(jī)的特點(diǎn)
冰箱壓縮機(jī)的作用_冰箱壓縮機(jī)修理價(jià)格是多少
虛擬機(jī):linux Kernel 添加 ZRAM 支持

制冷壓縮機(jī)的種類(lèi)_制冷壓縮機(jī)的結(jié)構(gòu)

評(píng)論