女人自慰AV免费观看内涵网,日韩国产剧情在线观看网址,神马电影网特片网,最新一级电影欧美,在线观看亚洲欧美日韩,黄色视频在线播放免费观看,ABO涨奶期羡澄,第一导航fulione,美女主播操b

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

buffers內(nèi)存與cached內(nèi)存的區(qū)別

嵌入式與Linux那些事 ? 來源:嵌入式與Linux那些事 ? 2024-07-29 14:17 ? 次閱讀

free 命令是Linux系統(tǒng)上查看內(nèi)存使用狀況最常用的工具,然而很少有人能說清楚 “buffers” 與 “cached” 之間的區(qū)別:

721df7b0-4d61-11ef-b8af-92fbcf53809c.png

我們先拋出結(jié)論,如果你對(duì)研究過程感興趣可以繼續(xù)閱讀后面的段落:

buffers 表示塊設(shè)備(block device)所占用的緩存頁,包括:直接讀寫塊設(shè)備、以及文件系統(tǒng)元數(shù)據(jù)(metadata),比如SuperBlock所使用的緩存頁;

cached 表示普通文件數(shù)據(jù)所占用的緩存頁。

下面是分析過程:

先用 strace 跟蹤 free 命令,看看它是如何計(jì)算 buffers 和 cached 的:

#stracefree
...
open("/proc/meminfo",O_RDONLY)=3
lseek(3,0,SEEK_SET)=0
read(3,"MemTotal:3848656kB
MemF"...,2047)=1170
...

顯然 free 命令是從 /proc/meminfo 中讀取信息的,跟我們直接讀到的結(jié)果一樣:

#cat/proc/meminfo
MemTotal:3848656kB
MemFree:865640kB
Buffers:324432kB
Cached:2024904kB
...
SwapTotal:2031612kB
SwapFree:2031612kB
...
Shmem:5312kB
...

那么 /proc/meminfo 中的 Buffers 和 Cached 又是如何得來的呢?這回沒法偷懶,只能去看源代碼了。源代碼文件是:fs/proc/meminfo.c ,我們感興趣的函數(shù)是:meminfo_proc_show(),閱讀得知:

Cached 來自于以下公式:

global_page_state(NR_FILE_PAGES)–total_swapcache_pages–i.bufferram

global_page_state(NR_FILE_PAGES) 表示所有的緩存頁(page cache)的總和,它包括:

Cached

Buffers 也就是上面公式中的 i.bufferram,來自于 nr_blockdev_pages() 函數(shù)的返回值。

交換區(qū)緩存(swap cache)

global_page_state(NR_FILE_PAGES) 來自 vmstat[NR_FILE_PAGES],vmstat[NR_FILE_PAGES] 可以通過 /proc/vmstat 來查看,表示所有緩存頁的總數(shù)量:

#cat/proc/vmstat
...
nr_file_pages587334
...

注意以上nr_file_pages是以page為單位(一個(gè)page等于4KB),而free命令是以KB為單位的。

直接修改 nr_file_pages 的內(nèi)核函數(shù)是:__inc_zone_page_state(page, NR_FILE_PAGES) 和__dec_zone_page_state(page, NR_FILE_PAGES),一個(gè)用于增加,一個(gè)用于減少。

Swap Cache是什么?

用戶進(jìn)程的內(nèi)存頁分為兩種:file-backed pages(與文件對(duì)應(yīng)的內(nèi)存頁)和anonymous pages(匿名頁)。匿名頁(anonymous pages)是沒有關(guān)聯(lián)任何文件的,比如用戶進(jìn)程通過malloc()申請(qǐng)的內(nèi)存頁,如果發(fā)生swapping換頁,它們沒有關(guān)聯(lián)的文件進(jìn)行回寫,所以只能寫入到交換區(qū)里。

交換區(qū)可以包括一個(gè)或多個(gè)交換區(qū)設(shè)備(裸盤、邏輯卷、文件都可以充當(dāng)交換區(qū)設(shè)備),每一個(gè)交換區(qū)設(shè)備在內(nèi)存里都有對(duì)應(yīng)的swap cache,可以把swap cache理解為交換區(qū)設(shè)備的page cache:page cache對(duì)應(yīng)的是一個(gè)個(gè)文件,swap cache對(duì)應(yīng)的是一個(gè)個(gè)交換區(qū)設(shè)備,kernel管理swap cache與管理page cache一樣,用的都是radix-tree,唯一的區(qū)別是:page cache與文件的對(duì)應(yīng)關(guān)系在打開文件時(shí)就確定了,而一個(gè)匿名頁只有在即將被swap-out的時(shí)候才決定它會(huì)被放到哪一個(gè)交換區(qū)設(shè)備,即匿名頁與swap cache的對(duì)應(yīng)關(guān)系在即將被swap-out時(shí)才確立。

并不是每一個(gè)匿名頁都在swap cache中,只有以下情形之一的匿名頁才在:

匿名頁即將被swap-out時(shí)會(huì)先被放進(jìn)swap cache,但通常只存在很短暫的時(shí)間,因?yàn)榫o接著在pageout完成之后它就會(huì)從swap cache中刪除,畢竟swap-out的目的就是為了騰出空閑內(nèi)存;【注:參見mm/vmscan.c: shrink_page_list(),它調(diào)用的add_to_swap()會(huì)把swap cache頁面標(biāo)記成dirty,然后它調(diào)用try_to_unmap()將頁面對(duì)應(yīng)的page table mapping都刪除,再調(diào)用pageout()回寫dirty page,最后try_to_free_swap()會(huì)把該頁從swap cache中刪除。】

曾經(jīng)被swap-out現(xiàn)在又被swap-in的匿名頁會(huì)在swap cache中,直到頁面中的內(nèi)容發(fā)生變化、或者原來用過的交換區(qū)空間被回收為止。【注:當(dāng)匿名頁的內(nèi)容發(fā)生變化時(shí)會(huì)刪除對(duì)應(yīng)的swap cache,代碼參見mm/swapfile.c: reuse_swap_page()。】

cached:

Cached 表示除去 buffers 和 swap cache 之外,剩下的也就是普通文件的緩存頁的數(shù)量:

global_page_state(NR_FILE_PAGES)–total_swapcache_pages–i.bufferram

所以關(guān)鍵還是要理解 buffers 是什么含義。

buffers:

從源代碼中看到,buffers 來自于 nr_blockdev_pages() 函數(shù)的返回值:

longnr_blockdev_pages(void)
{
structblock_device*bdev;
longret=0;
spin_lock(&bdev_lock);
list_for_each_entry(bdev,&all_bdevs,bd_list){
ret+=bdev->bd_inode->i_mapping->nrpages;
}
spin_unlock(&bdev_lock);
returnret;
}

這段代碼的意思是遍歷所有的塊設(shè)備(block device),累加每個(gè)塊設(shè)備的inode的i_mapping的頁數(shù),統(tǒng)計(jì)得到的就是 buffers。顯然 buffers 是與塊設(shè)備直接相關(guān)的。

那么誰會(huì)更新塊設(shè)備的緩存頁數(shù)量(nrpages)呢?我們繼續(xù)向下看。

搜索kernel源代碼發(fā)現(xiàn),最終點(diǎn)我更新mapping->nrpages字段的函數(shù)就是:

pagemap.h:add_to_page_cache
>filemap.c:add_to_page_cache_locked
C__add_to_page_cache_locked
>page_cache_tree_insert
和:
filemap.c:delete_from_page_cache
>__delete_from_page_cache
>page_cache_tree_delete
staticinlineintadd_to_page_cache(structpage*page,
structaddress_space*mapping,pgoff_toffset,gfp_tgfp_mask)
{
interror;

__set_page_locked(page);
error=add_to_page_cache_locked(page,mapping,offset,gfp_mask);
if(unlikely(error))
__clear_page_locked(page);
returnerror;
}

voiddelete_from_page_cache(structpage*page)
{
structaddress_space*mapping=page->mapping;
void(*freepage)(structpage*);

BUG_ON(!PageLocked(page));

freepage=mapping->a_ops->freepage;
spin_lock_irq(&mapping->tree_lock);
__delete_from_page_cache(page,NULL);
spin_unlock_irq(&mapping->tree_lock);
mem_cgroup_uncharge_cache_page(page);

if(freepage)
freepage(page);
page_cache_release(page);
}

這兩個(gè)函數(shù)是通用的,block device 和 文件inode 都可以調(diào)用,至于更新的是塊設(shè)備的(buffers)還是文件的(cached),取決于參數(shù)變量mapping:如果mapping對(duì)應(yīng)的是塊設(shè)備,那么相應(yīng)的統(tǒng)計(jì)信息會(huì)反映在 buffers 中;如果mapping對(duì)應(yīng)的是文件inode,影響的就是 cached。我們下面看看kernel中哪些地方會(huì)把塊設(shè)備的mapping傳遞進(jìn)來。

首先是塊設(shè)備本身,打開時(shí)使用 bdev->bd_inode->i_mapping。

staticintblkdev_open(structinode*inode,structfile*filp)
{
structblock_device*bdev;

/*
*Preservebackwardscompatibilityandallowlargefileaccess
*evenifuserspacedoesn'taskforitexplicitly.Somemkfs
*binaryneedsit.Wemightwanttodropthisworkaround
*duringanunstablebranch.
*/
filp->f_flags|=O_LARGEFILE;

if(filp->f_flags&O_NDELAY)
filp->f_mode|=FMODE_NDELAY;
if(filp->f_flags&O_EXCL)
filp->f_mode|=FMODE_EXCL;
if((filp->f_flags&O_ACCMODE)==3)
filp->f_mode|=FMODE_WRITE_IOCTL;

bdev=bd_acquire(inode);
if(bdev==NULL)
return-ENOMEM;

filp->f_mapping=bdev->bd_inode->i_mapping;

returnblkdev_get(bdev,filp->f_mode,filp);
}

其次,文件系統(tǒng)的Superblock也是使用塊設(shè)備:

structsuper_block{
...
structblock_device*s_bdev;
...
}

intinode_init_always(structsuper_block*sb,structinode*inode)
{
...
if(sb->s_bdev){
structbacking_dev_info*bdi;

bdi=sb->s_bdev->bd_inode->i_mapping->backing_dev_info;
mapping->backing_dev_info=bdi;
}
...
}

sb表示SuperBlock,s_bdev就是塊設(shè)備。Superblock是文件系統(tǒng)的metadata(元數(shù)據(jù)),不屬于文件,沒有對(duì)應(yīng)的inode,所以,對(duì)metadata操作所涉及的緩存頁都只能利用塊設(shè)備mapping,算入 buffers 的統(tǒng)計(jì)值內(nèi)。

如果文件含有間接塊(indirect blocks),因?yàn)殚g接塊也屬于metadata,所以走的也是塊設(shè)備的mapping。查看源代碼,果然如此:

ext4_get_blocks
->ext4_ind_get_blocks
->ext4_get_branch
->sb_getblk

staticinlinestructbuffer_head*
sb_getblk(structsuper_block*sb,sector_tblock)
{
return__getblk(sb->s_bdev,block,sb->s_blocksize);
}

這樣我們就知道了buffers 是塊設(shè)備(block device)占用的緩存頁,分為兩種情況:

直接對(duì)塊設(shè)備進(jìn)行讀寫操作;

文件系統(tǒng)的metadata(元數(shù)據(jù)),比如 SuperBlock。

驗(yàn)證:

現(xiàn)在我們來做個(gè)測試,驗(yàn)證一下上述結(jié)論。既然文件系統(tǒng)的metadata會(huì)用到 buffers,我們用 find 命令掃描文件系統(tǒng),觀察 buffers 增加的情況:

#free
totalusedfreesharedbufferscached
Mem:3848656288950895914853162638962023340
-/+buffers/cache:6022723246384
Swap:203161202031612

#find/-nameabc.def

#free
totalusedfreesharedbufferscached
Mem:3848656298405286460453203196122023348
-/+buffers/cache:6410923207564
Swap:203161202031612

再測試一下直接讀取block device,觀察buffers增加的現(xiàn)象:

#free
totalusedfreesharedbufferscached
Mem:3848656300694484171253163310202028648
-/+buffers/cache:6472763201380
Swap:203161202031612

#ddif=/dev/sda1of=/dev/nullcount=2000
2000+0recordsin
2000+0recordsout
1024000bytes(1.0MB)copied,0.026413s,38.8MB/s

#free
totalusedfreesharedbufferscached
Mem:3848656300770484095253163318722028692
-/+buffers/cache:6471403201516
Swap:203161202031612

結(jié)論:

free 命令所顯示的 buffers 表示塊設(shè)備(block device)所占用的緩存頁,包括直接讀寫塊設(shè)備、以及文件系統(tǒng)元數(shù)據(jù)(metadata)如SuperBlock所使用的緩存頁;而 cached 表示普通文件所占用的緩存頁。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 內(nèi)存
    +關(guān)注

    關(guān)注

    8

    文章

    3108

    瀏覽量

    74979
  • Linux系統(tǒng)
    +關(guān)注

    關(guān)注

    4

    文章

    603

    瀏覽量

    28292
  • 命令
    +關(guān)注

    關(guān)注

    5

    文章

    726

    瀏覽量

    22668
  • Buffers
    +關(guān)注

    關(guān)注

    0

    文章

    13

    瀏覽量

    10543

原文標(biāo)題:【內(nèi)存】buffers與cached的區(qū)別

文章出處:【微信號(hào):嵌入式與Linux那些事,微信公眾號(hào):嵌入式與Linux那些事】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    堆棧內(nèi)存和堆內(nèi)存之間的區(qū)別

    編寫有效的代碼需要了解堆棧和堆內(nèi)存,這使其成為學(xué)習(xí)編程的重要組成部分。不僅如此,新程序員或職場老手都應(yīng)該完全熟悉堆棧內(nèi)存和堆內(nèi)存之間的區(qū)別,以便編寫有效且優(yōu)化的代碼。
    發(fā)表于 08-07 12:23 ?882次閱讀
    堆棧<b class='flag-5'>內(nèi)存</b>和堆<b class='flag-5'>內(nèi)存</b>之間的<b class='flag-5'>區(qū)別</b>

    Linux上對(duì)進(jìn)程進(jìn)行內(nèi)存分析和內(nèi)存泄漏定位

    內(nèi)存管理并不熟悉,不過上述說法,可以通過下面的方法來驗(yàn)證:一、系統(tǒng)內(nèi)存。在proc目錄下的meminfo文件描述系統(tǒng)內(nèi)存的使用情況,可用的物理內(nèi)存=memfree+
    發(fā)表于 07-09 08:15

    Linux如何設(shè)置虛擬內(nèi)存

    1、打開終端,切換到root用戶,輸入:free -m查看內(nèi)存狀態(tài)[root@lxt lxt]# free -mtotal used free shared buffers cached
    發(fā)表于 07-23 07:47

    free命令介紹!內(nèi)存的分類!

    上面輸出的結(jié)果比較難理解的可能是第三行,為什么要向用戶展示這行數(shù)據(jù)呢?內(nèi)存使用量減去系統(tǒng)buffer/cached內(nèi)存表示何意呢?系統(tǒng)空閑內(nèi)存加上buffer/
    的頭像 發(fā)表于 09-10 17:21 ?4959次閱讀

    Linux吃掉我的內(nèi)存

    系統(tǒng)空閑的內(nèi)存buffers/cached好處 Linux 內(nèi)存管理做了很多精心的設(shè)計(jì),除了對(duì)dentry進(jìn)行緩存(用于VFS,加速文件路徑名到inode的轉(zhuǎn)換),還采取了兩種主要C
    發(fā)表于 04-02 14:32 ?213次閱讀

    電腦中硬盤和內(nèi)存區(qū)別是什么

    很多購買電腦的同學(xué)仍然還不清楚內(nèi)存和硬盤到底有什么區(qū)別,在電腦里面有什么作用,容易把內(nèi)存當(dāng)硬盤或把硬盤當(dāng)內(nèi)存,下面小編通俗易懂的來給大家講講硬盤跟內(nèi)
    發(fā)表于 12-22 11:13 ?1.1w次閱讀

    顯存和內(nèi)存有什么區(qū)別

    顯存和內(nèi)存有什么區(qū)別?兩者有工作對(duì)象、存儲(chǔ)速度和容量的區(qū)別。工作對(duì)象方面,顯存只為GPU暫存資料,而內(nèi)存則是為CPU和系統(tǒng)緩存資料空間;存儲(chǔ)速度方面,GDDR6顯存速度最高可達(dá)72GB
    發(fā)表于 05-19 10:46 ?2.4w次閱讀

    內(nèi)存套條和單條的區(qū)別

    同型號(hào)的內(nèi)存條,套裝往往要比單條還要貴一些。講道理來說,同型號(hào)同容量同頻率的內(nèi)存條價(jià)格應(yīng)該一樣,但是實(shí)際上他們的價(jià)格是有區(qū)別的,為什么會(huì)有這樣的差別呢?內(nèi)存套條和單條有什么
    發(fā)表于 05-25 10:11 ?5472次閱讀

    低電壓內(nèi)存和普通內(nèi)存區(qū)別有哪些

    在選購筆記本的時(shí)候,有的型號(hào)會(huì)標(biāo)注為低電壓的內(nèi)存條或者是后綴帶有L,那么低電壓內(nèi)存和普通內(nèi)存區(qū)別有哪些,下面就為大家?guī)硐嚓P(guān)的介紹。
    發(fā)表于 05-25 10:14 ?4968次閱讀

    內(nèi)存溢出和內(nèi)存泄露的區(qū)別_內(nèi)存溢出的原因以及解決方法

    內(nèi)存溢出和內(nèi)存泄露的區(qū)別是什么?內(nèi)存溢出怎么解決?內(nèi)存溢出是指程序在申請(qǐng)內(nèi)存時(shí),沒有足夠的
    發(fā)表于 06-01 10:27 ?3050次閱讀

    內(nèi)存和硬盤的區(qū)別與作用

    在定義方面它們有本質(zhì)的區(qū)別,硬盤屬于“ 非易失性存儲(chǔ)器”,而內(nèi)存是“隨機(jī)存取存儲(chǔ)器”,屬于“易失性存儲(chǔ)設(shè)備“。
    發(fā)表于 05-17 15:40 ?3346次閱讀

    內(nèi)存與外存的關(guān)鍵區(qū)別

    內(nèi)存和外存是計(jì)算機(jī)存儲(chǔ)的兩種不同形式,兩者雖然都是存儲(chǔ)數(shù)據(jù)的方式,但是卻有許多區(qū)別。本文將從定義、結(jié)構(gòu)、速度、容量、使用、價(jià)格等方面探討內(nèi)存與外存的關(guān)鍵區(qū)別
    的頭像 發(fā)表于 06-10 15:06 ?9339次閱讀

    內(nèi)存溢出與內(nèi)存泄漏:定義、區(qū)別與解決方案

    內(nèi)存溢出與內(nèi)存泄漏:定義、區(qū)別與解決方案? 內(nèi)存溢出和內(nèi)存泄漏是計(jì)算機(jī)科學(xué)中常見的問題,在開發(fā)和調(diào)試過程中經(jīng)常會(huì)遇到。本文將詳細(xì)介紹
    的頭像 發(fā)表于 12-19 14:10 ?3463次閱讀

    系統(tǒng)內(nèi)存和運(yùn)行內(nèi)存區(qū)別

    區(qū)別。 首先,系統(tǒng)內(nèi)存是指計(jì)算機(jī)中存儲(chǔ)程序和數(shù)據(jù)的硬件設(shè)備,也被稱為主存或內(nèi)存條。它是計(jì)算機(jī)用來臨時(shí)存儲(chǔ)數(shù)據(jù)和指令的地方,相當(dāng)于計(jì)算機(jī)的“大腦”。系統(tǒng)內(nèi)存的容量通常以GB(Gigab
    的頭像 發(fā)表于 01-15 16:32 ?4579次閱讀

    邏輯內(nèi)存和物理內(nèi)存區(qū)別

    邏輯內(nèi)存和物理內(nèi)存是計(jì)算機(jī)系統(tǒng)中兩個(gè)重要的概念,它們在計(jì)算機(jī)的運(yùn)行和數(shù)據(jù)處理中起著至關(guān)重要的作用。 1. 物理內(nèi)存(Physical Memory) 物理內(nèi)存,也稱為RAM(Rando
    的頭像 發(fā)表于 09-27 15:38 ?1607次閱讀