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

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

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

Linux總是以Lazy的方式給應(yīng)用程序分配內(nèi)存

Linux閱碼場 ? 來源:未知 ? 作者:李倩 ? 2018-04-27 15:10 ? 次閱讀

Linux總是以Lazy的方式給應(yīng)用程序分配內(nèi)存,包括堆、棧(函數(shù)調(diào)用越深,用的棧越多,最終發(fā)生page fault才得到棧)、代碼段、數(shù)據(jù)段。那么,這些已經(jīng)獲得到內(nèi)存的段會(huì)一直占用著內(nèi)存嗎?

1.page cache

Linux下讀寫文件,主要有兩種方式:

read/write

調(diào)用read讀文件,Linux內(nèi)核會(huì)申請(qǐng)一個(gè)page cache,然后把文件讀到page cache中,再將內(nèi)核空間的page cache拷貝到用戶空間的buf。

調(diào)用write寫文件,則將用戶空間buf拷貝到內(nèi)核空間page cache。

mmap

mmap可以避免buf從用戶空間到內(nèi)核空間的拷貝過程。

直接把文件映射成一個(gè)虛擬地址指針,這個(gè)指針指向內(nèi)核申請(qǐng)的page cache。內(nèi)核知道page cache與硬盤中文件的對(duì)應(yīng)關(guān)系。

使用mmap讀寫文件

注:讀寫權(quán)限需要對(duì)應(yīng),否則觸發(fā)page fault。

編譯執(zhí)行:

mmap看起來是由一個(gè)虛擬地址對(duì)應(yīng)一個(gè)文件(可以直接用指針訪問文件),本質(zhì)上是把進(jìn)程的虛擬地址空間映射到DRAM(內(nèi)核從這片區(qū)域申請(qǐng)內(nèi)存做page cache),而這個(gè)page cache對(duì)應(yīng)磁盤中的某個(gè)文件,且Linux內(nèi)核會(huì)維護(hù)page cache和磁盤中文件的交換關(guān)系。詳見下圖:

page cache可以看作內(nèi)存針對(duì)磁盤的一個(gè)緩存,應(yīng)用程序在寫文件時(shí),其實(shí)只是將內(nèi)容寫入了page cache,使用sync才能真的寫入文件。

ELF可執(zhí)行程序頭部會(huì)記錄代碼段的位置,代碼段的本質(zhì)就將ELF文件中的代碼段直接mmap映射到一個(gè)虛擬地址,且權(quán)限為R+X。

page cache可以極大的提高系統(tǒng)整體性能。如,進(jìn)程A讀一個(gè)文件,內(nèi)核空間會(huì)申請(qǐng)page cache與此文件對(duì)應(yīng),并記錄對(duì)應(yīng)關(guān)系,進(jìn)程B再次讀同樣的文件就會(huì)直接命中上一次的page cache,讀寫速度顯著提升。但注意,page cache會(huì)根據(jù)LRU算法(最近最少使用)進(jìn)行替換。

演示:page cache對(duì)程序執(zhí)行時(shí)間的影響

第一次多出很多硬盤io操作;第二次python的很多環(huán)境都在內(nèi)存中命中了,速度提升顯著。用\time -v命令再次對(duì)比:

附注:

i.swap:

動(dòng)詞:swapping,內(nèi)存與磁盤的顛簸行為

名字:swap分區(qū)

ii.cache可以通過/proc/sys/vm/drop_caches強(qiáng)行釋放,寫1釋放page cache,2釋放dentries和inode,3釋放兩者。

2.free命令的詳細(xì)解釋

上圖中,buffers與cached都是文件系統(tǒng)的緩存,沒有本質(zhì)區(qū)別,唯一區(qū)別是背景不同:

i.當(dāng)以文件系統(tǒng)(ext4,xfs等)的形式去訪問文件系統(tǒng)中的文件,如mount /dev/sda1 /mnt后,/mnt目錄下會(huì)有很多文件,訪問這類文件所產(chǎn)生的cache就對(duì)應(yīng)free命令顯示的cached列。

ii.直接訪問/dev/sda1時(shí),如用戶程序直接打開open(“dev/sda1…)或執(zhí)行dd命令,以及文件系統(tǒng)本身去訪問裸分區(qū),所產(chǎn)生的cache對(duì)應(yīng)free命令顯示的buffers列。

參考下圖所示:

演示:讀硬盤裸分區(qū)導(dǎo)致free命令顯示內(nèi)容變化

linux kernel 3.14版本以后,已經(jīng)采用新的free命令,如下圖:

老版本free中-/+buffers/cache的含義如下圖:

新版本free中多出available,即是評(píng)估出現(xiàn)在還有多少內(nèi)存可供應(yīng)用程序使用。

3.file-backed的頁面和匿名頁

page cache和CPU內(nèi)部cache一樣,是可以被替換出去的。有文件背景的頁面可以swap到磁盤。EG. 啟動(dòng)firefox,跑一個(gè)oom的程序,前后對(duì)比firefox的smaps文件??梢钥闯鰂irefox在內(nèi)存緊張的情況下,代碼段、mmap的字體文件等都被替換出去而不駐留內(nèi)存了。

那么,沒有文件背景的匿名頁是如何交換回收的呢?是否常住內(nèi)存?詳見下圖:

有文件背景的頁面和匿名頁都需要swap,有文件背景的頁面向自己的文件背景中交換,匿名頁向swap分區(qū)和swapfile中交換。即使編譯內(nèi)核時(shí)將CONFIG_SWAP關(guān)閉(只是關(guān)閉了匿名頁的交換),linux內(nèi)核中kswapd的線程還是會(huì)swap有文件背景的頁面。

Linux有三個(gè)水位:min,low,high。一旦內(nèi)存達(dá)到低水位時(shí),后臺(tái)自動(dòng)回收直到回收到高水位。當(dāng)內(nèi)存到達(dá)min水位時(shí),直接堵住進(jìn)程進(jìn)行回收。

匿名頁和有文件背景的頁面都有可能被回收,/proc/sys/vm/swappiness值比較大時(shí),傾向回收匿名頁;swappiness值比較小時(shí)傾向回收有文件背景的頁面?;厥账惴ń詾長RU。

附注:

數(shù)據(jù)段比較特殊,在沒有寫的情況是有文件背景的,但被寫后就變?yōu)槟涿摗?/p>

Windows中的虛擬內(nèi)存就相當(dāng)于Linux的swapfile。

4.頁面回收和LRU

如上圖,運(yùn)行到第4列時(shí),第1頁最不活躍。運(yùn)行到第5列時(shí)又把第1頁踏了一次,此時(shí)第2頁變?yōu)樽畈换钴S的。運(yùn)行到第6列時(shí)又把第2頁踏了一次,此時(shí)第3頁變?yōu)樽畈换钴S的,所以在第7列時(shí),由于要訪問一個(gè)新的第5頁,3就被替換出去。

5.swap以及zRAM

嵌入式系統(tǒng)受flash限制,很少使用swap分區(qū),一般都swapoff。所以嵌入式系統(tǒng)引入zRAM技術(shù)。

zRAM直接把一塊內(nèi)存模擬成一個(gè)硬盤分區(qū),當(dāng)作swap分區(qū)使用,此分區(qū)自帶透明壓縮功能,當(dāng)匿名頁向zRAM分區(qū)寫時(shí),Linux內(nèi)核使CPU自動(dòng)對(duì)匿名頁進(jìn)行壓縮。接下來,當(dāng)應(yīng)用程序又執(zhí)行到剛才的匿名頁時(shí),由于此頁已經(jīng)被swap到zRAM中,內(nèi)存中沒有命中,頁表也沒有命中,所以此時(shí)再去訪問這塊內(nèi)存時(shí)再次發(fā)生page fault,Linux就從zRAM分區(qū)中將匿名頁透明的解壓出來還到內(nèi)存中。

zRAM的特點(diǎn)是用內(nèi)存來做swap分區(qū),透明壓(兩頁匿名頁有可能被壓縮成一頁),透明解(一頁解壓成兩頁),這樣其實(shí)相當(dāng)于擴(kuò)大了內(nèi)存,但會(huì)多損耗一些CPU。

聲明:本文內(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)投訴
  • Linux
    +關(guān)注

    關(guān)注

    87

    文章

    11123

    瀏覽量

    207919
  • 內(nèi)存管理
    +關(guān)注

    關(guān)注

    0

    文章

    167

    瀏覽量

    14099

原文標(biāo)題:郝健: Linux內(nèi)存管理學(xué)習(xí)筆記-第4節(jié)課

文章出處:【微信號(hào):LinuxDev,微信公眾號(hào):Linux閱碼場】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    Linux內(nèi)存系統(tǒng): Linux 內(nèi)存分配算法

    、伙伴系統(tǒng)算法——組織結(jié)構(gòu)1) 概念· 為內(nèi)核提供了一種用于分配一組連續(xù)的頁而建立的一種高效的分配策略,并有效的解決了外碎片問題· 分配內(nèi)存區(qū)是以
    發(fā)表于 08-24 07:44

    內(nèi)核的內(nèi)存是如何進(jìn)行分配

    嵌入式LINUX驅(qū)動(dòng)學(xué)習(xí)之12內(nèi)核內(nèi)存分配一、頭文件、函數(shù)及說明:一、頭文件、函數(shù)及說明://頭文件位置 : include/linux/slab.h/*申請(qǐng)
    發(fā)表于 12-17 06:44

    如何通過TZASC分配安全內(nèi)存并通過OP-TEE中的可信應(yīng)用程序訪問它?

    了 optee,然后運(yùn)行了 optee_hello_world 示例,它似乎工作正常。 我現(xiàn)在想為安全區(qū)域分配一些內(nèi)存并使用受信任的應(yīng)用程序訪問它。我檢查了 SRM,但我需要更清楚地了解我在
    發(fā)表于 05-04 08:46

    Linux內(nèi)存管理中的Slab分配機(jī)制

    早期Linux內(nèi)存分配機(jī)制采用伙伴算法, 當(dāng)請(qǐng)求分配內(nèi)存大小為幾十個(gè)字節(jié)或幾百個(gè)字節(jié)時(shí)會(huì)產(chǎn)生內(nèi)存
    發(fā)表于 04-24 10:49 ?11次下載

    嵌入式Linux NFS方式應(yīng)用程序的實(shí)現(xiàn)

    嵌入式Linux NFS方式應(yīng)用程序的實(shí)現(xiàn):本文在以ARM9 內(nèi)核芯片,處理器為S3C2410 構(gòu)造的開發(fā)板系統(tǒng)上,詳細(xì)討論了如何配置嵌入式Linux NFS 開發(fā)環(huán)境,并通過一個(gè)具
    發(fā)表于 08-02 14:48 ?39次下載

    一種用于交互型CAD的內(nèi)存管理系統(tǒng)設(shè)計(jì)

    交互型CAD系統(tǒng)得頻繁的分配與釋放內(nèi)存。頻繁的內(nèi)存分配與釋放是降低應(yīng)用程序性能的重要原因。應(yīng)用程序
    發(fā)表于 02-22 13:54 ?20次下載

    Android應(yīng)用程序內(nèi)存泄漏的原因及規(guī)避方法

    引言 Android應(yīng)用程序內(nèi)存使用的問題經(jīng)常容易被忽視,在傳統(tǒng)的編程語言中(例如C語言),回收內(nèi)存的任務(wù)是由程序本身來完成的,程序可以顯
    發(fā)表于 10-19 14:52 ?0次下載
    Android<b class='flag-5'>應(yīng)用程序</b><b class='flag-5'>內(nèi)存</b>泄漏的原因及規(guī)避方法

    淺談內(nèi)存分配方式 避免內(nèi)存浪費(fèi)問題

    說到內(nèi)存分配方式,就不得不提連續(xù)分配方式。這種方式是指為一個(gè)用戶程序分配一個(gè)連續(xù)的
    發(fā)表于 03-03 11:22 ?1373次閱讀

    單片機(jī)的程序內(nèi)存和FLASH中應(yīng)該如何進(jìn)行空間分配

    一句話:基于速度問題,電腦使用硬盤存儲(chǔ)程序,運(yùn)行時(shí),在內(nèi)存分配空間變量,加載程序內(nèi)存中,在
    發(fā)表于 09-18 17:20 ?3次下載
    單片機(jī)的<b class='flag-5'>程序</b>在<b class='flag-5'>內(nèi)存</b>和FLASH中應(yīng)該如何進(jìn)行空間<b class='flag-5'>分配</b>

    Linux操作系統(tǒng)知識(shí)講解:走進(jìn)Linux 內(nèi)存分配算法

    Linux操作系統(tǒng)知識(shí)講解:走進(jìn)Linux 內(nèi)存分配算法
    的頭像 發(fā)表于 08-28 10:57 ?5332次閱讀
    <b class='flag-5'>Linux</b>操作系統(tǒng)知識(shí)講解:走進(jìn)<b class='flag-5'>Linux</b> <b class='flag-5'>內(nèi)存</b><b class='flag-5'>分配</b>算法

    嵌入式Linux應(yīng)用程序例程

    嵌入式Linux應(yīng)用程序例程(arm嵌入式開發(fā)步驟)-嵌入式Linux應(yīng)用程序例程,有需要的可以參考!
    發(fā)表于 07-30 13:23 ?16次下載
    嵌入式<b class='flag-5'>Linux</b><b class='flag-5'>應(yīng)用程序</b>例程

    C語言堆棧程序內(nèi)存分配

    ? ? 程序內(nèi)存分配 ? ????一個(gè)由C/C++編譯的程序占用的內(nèi)存分為以下幾個(gè)部分: 棧區(qū)(stack)— 由編譯器自動(dòng)
    的頭像 發(fā)表于 10-21 14:51 ?2237次閱讀

    C語言程序編譯后內(nèi)存地址的分配

    )C程序內(nèi)存分配1.內(nèi)存分配圖解2.內(nèi)存分配介紹(二
    發(fā)表于 01-13 14:23 ?1次下載
    C語言<b class='flag-5'>程序</b>編譯后<b class='flag-5'>內(nèi)存</b>地址的<b class='flag-5'>分配</b>

    Linux內(nèi)核引導(dǎo)內(nèi)存分配器的原理

    Linux內(nèi)核引導(dǎo)內(nèi)存分配器使用的是伙伴系統(tǒng)算法。這種算法是一種用于動(dòng)態(tài)內(nèi)存分配的高效算法,它將內(nèi)存
    發(fā)表于 04-03 14:52 ?344次閱讀

    OneCommand Manager應(yīng)用程序Linux

    電子發(fā)燒友網(wǎng)站提供《OneCommand Manager應(yīng)用程序Linux版.pdf》資料免費(fèi)下載
    發(fā)表于 08-15 14:44 ?0次下載
    OneCommand Manager<b class='flag-5'>應(yīng)用程序</b><b class='flag-5'>Linux</b>版