內(nèi)存問(wèn)題分析(二)-內(nèi)存管理基礎(chǔ)(下)

接上篇繼續(xù)總結(jié)內(nèi)存管理基礎(chǔ)承粤。

五择葡、內(nèi)存回收

無(wú)論計(jì)算機(jī)上有多少內(nèi)存都是不夠的肴茄,因而linux kernel需要通過(guò)內(nèi)存回收策略來(lái)保證系統(tǒng)持續(xù)有內(nèi)存使用纯丸。

5.1 基本概念

1. 頁(yè)分類(按有無(wú)文件背景頁(yè)面主要分兩種)
文件頁(yè)(file-backed page):有文件背景頁(yè)面偏形。可以直接和硬盤對(duì)應(yīng)的文件進(jìn)行交換觉鼻。
匿名頁(yè)(anonymous page):無(wú)文件背景頁(yè)面俊扭。如進(jìn)程堆、棧坠陈、數(shù)據(jù)段使用的頁(yè)等萨惑,無(wú)法直接跟磁盤交換,但是可以跟swap區(qū)進(jìn)行交換仇矾。

2. 緩存
對(duì)于有文件背景的頁(yè)面庸蔼,程序去讀文件時(shí),可以通過(guò)read也可以通過(guò)mmap去讀贮匕。通過(guò)任何一種方式從磁盤讀文件時(shí)姐仅,內(nèi)核都會(huì)給你申請(qǐng)一個(gè)page cache,來(lái)緩存硬盤上的內(nèi)容刻盐。這樣掏膏,讀過(guò)一遍的數(shù)據(jù)下次再讀的時(shí)候就直接從page cache里去拿,提升了性能和訪問(wèn)速度敦锌。

而這里需要補(bǔ)充兩對(duì)概念:
1)對(duì)比兩種文件操作的方式:read/write 和 mmap

read/write: 常規(guī)文件操作為了提高讀寫效率和保護(hù)磁盤馒疹,使用了page cache機(jī)制。這樣造成讀文件時(shí)需要先將文件頁(yè)從磁盤拷貝到頁(yè)緩存中乙墙,由于頁(yè)緩存處在內(nèi)核空間颖变,不能被用戶進(jìn)程直接尋址,所以還需要將頁(yè)緩存中數(shù)據(jù)頁(yè)再次拷貝到內(nèi)存對(duì)應(yīng)的用戶空間中伶丐。這樣悼做,通過(guò)了兩次數(shù)據(jù)拷貝過(guò)程,才能完成進(jìn)程對(duì)文件內(nèi)容的獲取任務(wù)哗魂。寫操作也是一樣肛走,待寫入的buffer在內(nèi)核空間不能直接訪問(wèn),必須要先拷貝至內(nèi)核空間對(duì)應(yīng)的主存录别,再寫回磁盤中(延遲寫回)朽色,也是需要兩次數(shù)據(jù)拷貝邻吞。但是讀過(guò)的數(shù)據(jù)下次再讀就直接從page cache里去拿了, 這時(shí)效率也是很高的。

mmap:創(chuàng)建新的虛擬內(nèi)存區(qū)域和建立文件磁盤地址和虛擬內(nèi)存區(qū)域映射這兩步葫男,沒(méi)有任何文件拷貝操作抱冷。而之后訪問(wèn)數(shù)據(jù)時(shí)發(fā)現(xiàn)內(nèi)存中并無(wú)數(shù)據(jù)而發(fā)起的缺頁(yè)異常過(guò)程,可以通過(guò)已經(jīng)建立好的映射關(guān)系梢褐,只使用一次數(shù)據(jù)拷貝旺遮,就從磁盤中將數(shù)據(jù)傳入內(nèi)存的用戶空間中,供進(jìn)程使用盈咳。對(duì)文件的讀取操作跨過(guò)了頁(yè)緩存耿眉,減少了數(shù)據(jù)的拷貝次數(shù),用內(nèi)存讀寫取代I/O讀寫鱼响,提高了文件讀取效率鸣剪。

2)cache 與 buffer
通過(guò)文件系統(tǒng)來(lái)訪問(wèn)文件產(chǎn)生的緩存記錄為cache。
直接操作磁盤產(chǎn)生的緩存記錄為buffer丈积。

這里cache提升了文件讀寫的性能和速度筐骇,但是也占用了物理內(nèi)存空間,并且在程序運(yùn)行結(jié)束后江滨,cache memory也不會(huì)自動(dòng)釋放铛纬,而需要通過(guò)內(nèi)存回收策略來(lái)釋放。

5.2 哪些內(nèi)存可以回收

屬于內(nèi)核的大部分頁(yè)框是不能夠進(jìn)行回收的牙寞,比如內(nèi)核棧饺鹃、內(nèi)核代碼段莫秆、內(nèi)核數(shù)據(jù)段以及大部分內(nèi)核使用的頁(yè)框间雀。
進(jìn)程使用的頁(yè)框可以進(jìn)行回收的,比如進(jìn)程代碼段镊屎、進(jìn)程數(shù)據(jù)段惹挟、進(jìn)程堆棧、進(jìn)程訪問(wèn)文件時(shí)映射的文件頁(yè)缝驳、進(jìn)程間共享內(nèi)存使用的頁(yè)连锯。

5.3 頁(yè)回收方式

頁(yè)回寫:如果一個(gè)很少使用的頁(yè)的后備存儲(chǔ)器是一個(gè)塊設(shè)備(例如文件映射),則可以將內(nèi)存直接同步到塊設(shè)備用狱,騰出的頁(yè)面可以被重用运怖。
頁(yè)交換:如果頁(yè)面沒(méi)有后備存儲(chǔ)器,則可以交換到特定swap分區(qū)夏伊,再次被訪問(wèn)時(shí)再交換回內(nèi)存摇展。
頁(yè)丟棄:如果頁(yè)面的后備存儲(chǔ)器是一個(gè)文件,但文件內(nèi)容在內(nèi)存不能被修改(例如可執(zhí)行文件)溺忧,那么在當(dāng)前不需要的情況下可直接丟棄咏连。

5.4 頁(yè)回收算法-LRU

當(dāng)Linux系統(tǒng)內(nèi)存有盈余時(shí)盯孙,內(nèi)核會(huì)盡量多地使用內(nèi)存作為page cache,提高系統(tǒng)性能祟滴,page cache會(huì)被加入到文件類型的LRU鏈表中振惰,當(dāng)系統(tǒng)內(nèi)存緊張時(shí),會(huì)按一定的算法來(lái)回收內(nèi)存垄懂,下面簡(jiǎn)單了解下:

LRU鏈表按zone來(lái)配置骑晶,每個(gè)zone中都有一整套LRU鏈表。

而一個(gè)lru鏈表描述符中總共有5個(gè)雙向鏈表頭草慧,它們分別描述五中不同類型的鏈表:

  • LRU_INACTIVE_ANON:稱為非活動(dòng)匿名頁(yè)lru鏈表(swap)
  • LRU_ACTIVE_ANON:稱為活動(dòng)匿名頁(yè)lru鏈表(swap)
  • LRU_INACTIVE_FILE:稱為非活動(dòng)文件頁(yè)lru鏈表(磁盤)
  • LRU_ACTIVE_FILE:稱為活動(dòng)文件頁(yè)lru鏈表(磁盤)
  • LRU_UNEVICTABLE:此鏈表中保存的是此zone中所有禁止換出的頁(yè)的描述符透罢。

那么lru鏈表進(jìn)行的操作主要有以下幾種:

  • 將不處于lru鏈表的新頁(yè)放入到lru鏈表中
  • 將非活動(dòng)lru鏈表中的頁(yè)移動(dòng)到非活動(dòng)lru鏈表尾部
  • 將處于活動(dòng)lru鏈表的頁(yè)移動(dòng)到非活動(dòng)lru鏈表
  • 將處于非活動(dòng)lru鏈表的頁(yè)移動(dòng)到活動(dòng)lru鏈表
  • 將頁(yè)從lru鏈表中移除

LRU老化規(guī)則:頁(yè)面通過(guò)lru批處理,轉(zhuǎn)來(lái)轉(zhuǎn)去冠蒋,從活動(dòng)鏈表轉(zhuǎn)到非活動(dòng)鏈表羽圃,從非活動(dòng)鏈表靠前轉(zhuǎn)到鏈尾,在內(nèi)存回收時(shí)抖剿,非活動(dòng)鏈表鏈尾的頁(yè)被回收掉朽寞。

當(dāng)內(nèi)存緊張時(shí),優(yōu)先換出無(wú)臟數(shù)據(jù)的page cache(文件頁(yè)包含page cache)斩郎,直接丟棄脑融。其次才是匿名頁(yè)和有臟數(shù)據(jù)的文件頁(yè)的回收。遵循URL老化規(guī)則缩宜。通過(guò)Swappiness來(lái)確定更傾向于回收哪種更多一點(diǎn)肘迎,swappiness越大,越傾向于回收匿名頁(yè)锻煌,反之越傾向于回收文件頁(yè)妓布。將swapness=0則意味著不再交換匿名頁(yè),swapness=100, 盡量交換匿名頁(yè),Swappiness默認(rèn)值為60宋梧。

5.4 頁(yè)回收時(shí)機(jī)
周期性回收(被動(dòng)觸發(fā)):這是由后臺(tái)運(yùn)行的守護(hù)進(jìn)程 kswapd 完成的匣沼,回收的時(shí)機(jī)由水位控制。
直接頁(yè)面回收(主動(dòng)觸發(fā)):“內(nèi)存嚴(yán)重不足”事件的觸發(fā)捂龄。

如果操作系統(tǒng)在進(jìn)行了內(nèi)存回收操作之后仍然無(wú)法回收到足夠多的頁(yè)面以滿足上述內(nèi)存要求释涛,那么操作系統(tǒng)只有最后一個(gè)選擇,那就是使用 OOM( out of memory )killer倦沧,它從系統(tǒng)中挑選一個(gè)最合適的進(jìn)程殺死它唇撬,并釋放該進(jìn)程所占用的所有頁(yè)面。

5.4.1 水位控制

名稱 描述
high 內(nèi)存回收到該值時(shí)停止回收展融。
low 內(nèi)存到該值時(shí)觸發(fā)kswapd線程的內(nèi)存回收窖认。
min 如果剩余內(nèi)存減少到觸及這個(gè)水位,可認(rèn)為內(nèi)存嚴(yán)重不足,當(dāng)前進(jìn)程就會(huì)被堵住耀态,kernel會(huì)直接在這個(gè)進(jìn)程的進(jìn)程上下文里面做直接頁(yè)面回收轮傍。

注:由于每個(gè)ZONE是分別管理各自內(nèi)存的,因此每個(gè)ZONE都有這三個(gè)水位首装。

5.4.2 回收代碼調(diào)用路徑

頁(yè)面回收代碼調(diào)用路徑

直接頁(yè)面回收

系統(tǒng)會(huì)調(diào)用函數(shù) try_to_free_pages() 去檢查當(dāng)前內(nèi)存區(qū)域中的頁(yè)面创夜,回收那些最不常用的頁(yè)面。該函數(shù)會(huì)反復(fù)調(diào)用 shrink_zones() 以及 shrink_slab() 釋放一定數(shù)目的頁(yè)面仙逻,默認(rèn)值是 32 個(gè)頁(yè)面驰吓。如果在特定的循環(huán)次數(shù)內(nèi)沒(méi)有能夠成功釋放 32 個(gè)頁(yè)面,那么頁(yè)面回收會(huì)調(diào)用 OOM killer 選擇并殺死一個(gè)進(jìn)程系奉,然后釋放它占用的所有頁(yè)面檬贰。

注:OOM_killer是Linux自我保護(hù)的方式,當(dāng)內(nèi)存不足時(shí)不至于出現(xiàn)太嚴(yán)重問(wèn)題缺亮,有點(diǎn)壯士斷腕的意味翁涤。在kernel 2.6,內(nèi)存不足將喚醒oom_killer萌踱,挑出/proc/<pid>/oom_score最大者并將之kill掉葵礼。

定期(周期性)回收

kswapd進(jìn)程以水線為觸發(fā)點(diǎn),按LRU鏈表來(lái)進(jìn)行回收并鸵。系統(tǒng)會(huì)調(diào)用函數(shù)balance_pgdat()鸳粉,它主要調(diào)用的函數(shù)是 shrink_zone() 和 shrink_slab()。

5.4.3 函數(shù)介紹

shrink_zone()
該函數(shù)主要做了兩件事情:
1)將某些頁(yè)面從 active 鏈表移到 inactive 鏈表园担,這是由函數(shù) shrink_active_list() 實(shí)現(xiàn)的届谈。
2)從 inactive 鏈表中選定一定數(shù)目的頁(yè)面,將其放到一個(gè)臨時(shí)鏈表中弯汰,這由函數(shù) shrink_inactive_list() 完成艰山。該函數(shù)最終會(huì)調(diào)用 shrink_page_list() 去回收這些頁(yè)面。

shrink_slab()
該函數(shù)用來(lái)回收磁盤緩存所占用的頁(yè)面的蝙泼。Linux 操作系統(tǒng)并不清楚這類頁(yè)面是如何使用的程剥,所以如果希望操作系統(tǒng)回收磁盤緩存所占用的頁(yè)面劝枣,那么必須要向操作系統(tǒng)內(nèi)核注冊(cè) shrinker 函數(shù)汤踏,shrinker 函數(shù)會(huì)在內(nèi)存較少的時(shí)候主動(dòng)釋放一些該磁盤緩存占用的空間。函數(shù) shrink_slab() 會(huì)遍歷 shrinker 鏈表舔腾,從而對(duì)所有注冊(cè)了 shrinker 函數(shù)的磁盤緩存進(jìn)行處理溪胶。Android內(nèi)核的lowmemorykiller機(jī)制就是注冊(cè)了shrinker,內(nèi)存過(guò)低時(shí)選擇性殺死進(jìn)程來(lái)回收內(nèi)存稳诚。

shrink_page_list()
邏輯流程圖:

shrink_page_list()執(zhí)行邏輯
六哗脖、用戶空間內(nèi)存管理

6.1 Android用戶空間進(jìn)程劃分

  • Native進(jìn)程:不包含虛擬機(jī)實(shí)例的linux進(jìn)程。
  • Java進(jìn)程:包含了虛擬機(jī)實(shí)例的linux進(jìn)程。

6.2 內(nèi)存管理
6.2.1 Natvie進(jìn)程
1)內(nèi)存區(qū)域劃分:
Native進(jìn)程與Linux進(jìn)程一樣才避,虛擬內(nèi)存區(qū)域分為:代碼區(qū)橱夭、只讀常量區(qū)、全局區(qū)桑逝、BSS段棘劣、堆區(qū)、棧區(qū)


native進(jìn)程內(nèi)存區(qū)域劃分

代碼區(qū):存放函數(shù)體的二進(jìn)制代碼楞遏。
只讀常量區(qū):存放字符串常量茬暇,以及const修飾的全局變量 。
全局區(qū)/數(shù)據(jù)區(qū):存放已經(jīng)初始化的全局變量和已經(jīng)初始化用static修飾的局部變量寡喝。
BSS段:存放沒(méi)有初始化的全局變量和未初始化靜態(tài)局部變量糙俗,該區(qū)域會(huì)在main函數(shù)執(zhí)行前進(jìn)行自動(dòng)清零。
堆區(qū):一般由程序員分配釋放预鬓,若程序員不釋放巧骚,程序結(jié)束時(shí)可能由OS回收。注意它與數(shù)據(jù)結(jié)構(gòu)中的堆是兩回事格二,分配方式倒是類似于鏈表网缝。
棧區(qū):由編譯器自動(dòng)分配釋放,存放函數(shù)的參數(shù)值蟋定,局部變量的值等粉臊。其操作方式類似于數(shù)據(jù)結(jié)構(gòu)中的棧。

注意:棧區(qū)和堆區(qū)之間并沒(méi)有嚴(yán)格分割線驶兜,可以進(jìn)行微調(diào)扼仲,并且堆區(qū)分配一般從低地址到高地址分配,而棧區(qū)分配一般從高地址到低地址分配抄淑。

以上是標(biāo)準(zhǔn)劃分屠凶,但是對(duì)于一個(gè)進(jìn)程的內(nèi)存空間,邏輯上可以分為以下三部分:
程序區(qū): 程序的二進(jìn)制文件肆资。
靜態(tài)存儲(chǔ)區(qū):(只讀常量區(qū)矗愧、全局區(qū)、BSS段)全局變量和靜態(tài)變量郑原。
動(dòng)態(tài)存儲(chǔ)區(qū):(堆區(qū)唉韭、棧區(qū))本地變量。

注:
局部變量:在一個(gè)有限的范圍內(nèi)的變量犯犁,作用域是有限的属愤,對(duì)于程序來(lái)說(shuō),在一個(gè)函數(shù)體內(nèi)部聲明的普通變量都是局部變量酸役,局部變量會(huì)在棧上申請(qǐng)空間住诸,函數(shù)結(jié)束后驾胆,申請(qǐng)的空間會(huì)自動(dòng)釋放。
全局變量:在函數(shù)體外申請(qǐng)的贱呐,會(huì)被存放在全局(靜態(tài)區(qū))上丧诺,知道程序結(jié)束后才會(huì)被結(jié)束,這樣它的作用域就是整個(gè)程序奄薇。
靜態(tài)變量:和全局變量的存儲(chǔ)方式相同锅必,在函數(shù)體內(nèi)聲明為static就可以使此變量像全局變量一樣使用,不用擔(dān)心函數(shù)結(jié)束而被釋放惕艳。

2)內(nèi)存分配與回收
內(nèi)存的靜態(tài)分配和動(dòng)態(tài)分配的區(qū)別主要是兩個(gè):

  • 時(shí)間上:靜態(tài)分配發(fā)生在程序編譯和連接時(shí)搞隐,動(dòng)態(tài)分配則發(fā)生在程序調(diào)入和執(zhí)行時(shí)。
  • 空間上:堆都是動(dòng)態(tài)分配的远搪,沒(méi)有靜態(tài)分配的堆劣纲。棧有2種分配方式:靜態(tài)分配和動(dòng)態(tài)分配。靜態(tài)分配是編譯器完成的谁鳍,比如局部變量的分配癞季。動(dòng)態(tài)分配由函數(shù)malloc進(jìn)行分配。不過(guò)棧的動(dòng)態(tài)分配和堆不同倘潜,他的動(dòng)態(tài)分配是由編譯器進(jìn)行釋放绷柒,無(wú)需我們手工實(shí)現(xiàn)。

動(dòng)態(tài)內(nèi)存分配與回收
所謂動(dòng)態(tài)內(nèi)存分配涮因,就是指在程序執(zhí)行的過(guò)程中動(dòng)態(tài)地分配或者回收存儲(chǔ)空間的分配內(nèi)存的方法废睦。動(dòng)態(tài)內(nèi)存分配不象數(shù)組等靜態(tài)內(nèi)存分配方法那樣需要預(yù)先分配存儲(chǔ)空間,而是由系統(tǒng)根據(jù)程序的需要即時(shí)分配养泡,且分配的大小就是程序要求的大小嗜湃。

分配和回收操作函數(shù)介紹:
malloc:動(dòng)態(tài)內(nèi)存分配,用于在堆上申請(qǐng)一塊連續(xù)的指定大小的內(nèi)存區(qū)域澜掩,但是并沒(méi)有初始化购披。
calloc:則將初始化這部分的內(nèi)存,設(shè)置為0. calloc = malloc + memset(初始化工作)。
alloca:是向棧申請(qǐng)內(nèi)存,因此無(wú)需釋放肩榕。
realloc:則對(duì)malloc申請(qǐng)的內(nèi)存進(jìn)行大小的調(diào)整刚陡。
(注:這四個(gè)函數(shù)都是由free來(lái)釋放內(nèi)存。)

new :new 基于 malloc株汉,卻又高于malloc筐乳,是它的一個(gè)提升版本。首先new不是庫(kù)函數(shù)郎逃,它是一個(gè)關(guān)鍵字哥童,通過(guò)new操作符申請(qǐng)的內(nèi)存都在自由存儲(chǔ)區(qū),且不需要指定內(nèi)存塊大小褒翰。內(nèi)存分配失敗時(shí),會(huì)拋出bac_alloc異常,而不是返回一個(gè)NULL等等优训。new是通過(guò)delete來(lái)釋放內(nèi)存朵你,它同樣也是一個(gè)關(guān)鍵字。

6.2.2 Java進(jìn)程
從之前寫的系統(tǒng)啟動(dòng)流程中我們了解了揣非,zygote是java進(jìn)程的鼻祖抡医,它通過(guò)了Runtime啟動(dòng)了虛擬機(jī),并通過(guò)fork早敬,把虛擬機(jī)作為環(huán)境帶給了每一個(gè)應(yīng)用進(jìn)程忌傻。虛擬機(jī)的設(shè)計(jì)除了提供跨平臺(tái)能力之外,也提供了對(duì)象生命周期的管理搞监,內(nèi)存管理水孩,線程管理,安全和異常的管理等統(tǒng)一的處理方案琐驴。

1)內(nèi)存區(qū)域劃分
這部分之前文章有總結(jié):俘种,如下是JVM內(nèi)存劃分模型,其實(shí)Dalvik和ART都一樣绝淡,就是Heap的space結(jié)構(gòu)會(huì)有區(qū)別:

JVM內(nèi)存劃分模型

程序計(jì)數(shù)器:是一塊較小的線程私有的內(nèi)存空間宙刘,用來(lái)記錄正在執(zhí)行的虛擬機(jī)字節(jié)碼指令,以此來(lái)記錄當(dāng)前線程的運(yùn)行狀態(tài)牢酵;它是一個(gè)指針悬包,指向執(zhí)行引擎正在執(zhí)行的指令的地址。
虛擬機(jī)棧:棧是一塊連續(xù)的內(nèi)存區(qū)域馍乙,大小是由操作系統(tǒng)預(yù)定好的(2M左右)玉罐,它是先進(jìn)后出的隊(duì)列,進(jìn)出一一對(duì)應(yīng)潘拨,不產(chǎn)生碎片吊输,運(yùn)行效率穩(wěn)定高。局部變量的基本數(shù)據(jù)類型和引用存儲(chǔ)于棧中铁追,因?yàn)樗鼈儗儆诜椒ㄖ械淖兞考韭欤芷陔S方法而結(jié)束。
本地方法棧:針對(duì)Native方法的琅束,功能與虛擬機(jī)棧一致扭屁。
靜態(tài)存儲(chǔ)區(qū)(方法區(qū)):內(nèi)存在程序編譯的時(shí)候就已經(jīng)分配好,這塊內(nèi)存在程序整個(gè)運(yùn)行期間都存在涩禀。它主要存放靜態(tài)數(shù)據(jù)料滥、全局static數(shù)據(jù)和包含常量池。
:堆是不連續(xù)的內(nèi)存區(qū)域(因?yàn)橄到y(tǒng)是用鏈表來(lái)存儲(chǔ)空閑內(nèi)存地址艾船,自然不是連續(xù)的)葵腹,堆大小受限于計(jì)算機(jī)系統(tǒng)中有效的虛擬內(nèi)存(32bit系統(tǒng)理論上是4G)高每,所以堆的空間比較靈活,比較大践宴。對(duì)于堆呆万,頻繁的分配和回收內(nèi)存會(huì)造成大量?jī)?nèi)存碎片结闸,使程序效率降低。堆內(nèi)存用于存放引用的對(duì)象實(shí)體、成員變量全部存儲(chǔ)于堆中(包括基本數(shù)據(jù)類型总寻,引用和引用的對(duì)象實(shí)體剖膳,因?yàn)樗鼈儗儆陬惛绒龋悓?duì)象終究是要被new出來(lái)使用的)熙侍。

Java內(nèi)存玩的就是虛擬機(jī)劃分的一畝三分地,而大小是由系統(tǒng)設(shè)置的柒室,內(nèi)存的分配與回收都是虛擬機(jī)負(fù)責(zé)的渡贾。申請(qǐng)的內(nèi)存超過(guò)了一畝三分地就會(huì)oom,內(nèi)存不足會(huì)觸發(fā)gc伦泥,而gc又分串行g(shù)c與并行g(shù)c剥啤,art虛擬機(jī)優(yōu)化了gc環(huán)節(jié),大大縮短了全線程block的時(shí)長(zhǎng)不脯,但是如果明顯的內(nèi)存抖動(dòng)還是會(huì)造成卡頓問(wèn)題府怯。

好了,虛擬機(jī)內(nèi)存管理暫時(shí)不分析了防楷,之后有機(jī)會(huì)再單獨(dú)開(kāi)系列來(lái)分析牺丙,內(nèi)存管理基礎(chǔ)暫時(shí)就寫這么多,歇了复局。

參考:
https://blog.csdn.net/jasonchen_gbd/article/details/79462014
http://www.wowotech.net/memory_management/233.html
https://www.ibm.com/developerworks/cn/linux/l-cn-pagerecycle/
https://www.cnblogs.com/fah936861121/p/6878699.html
https://blog.csdn.net/Luoshengyang/article/details/42492621
https://blog.csdn.net/Luoshengyang/article/details/42555483

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末冲簿,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子亿昏,更是在濱河造成了極大的恐慌峦剔,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,183評(píng)論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件角钩,死亡現(xiàn)場(chǎng)離奇詭異吝沫,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)递礼,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,850評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門惨险,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人脊髓,你說(shuō)我怎么就攤上這事辫愉。” “怎么了将硝?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,766評(píng)論 0 361
  • 文/不壞的土叔 我叫張陵恭朗,是天一觀的道長(zhǎng)屏镊。 經(jīng)常有香客問(wèn)我,道長(zhǎng)冀墨,這世上最難降的妖魔是什么闸衫? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,854評(píng)論 1 299
  • 正文 為了忘掉前任涛贯,我火速辦了婚禮诽嘉,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘弟翘。我一直安慰自己虫腋,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,871評(píng)論 6 398
  • 文/花漫 我一把揭開(kāi)白布稀余。 她就那樣靜靜地躺著悦冀,像睡著了一般。 火紅的嫁衣襯著肌膚如雪睛琳。 梳的紋絲不亂的頭發(fā)上盒蟆,一...
    開(kāi)封第一講書(shū)人閱讀 52,457評(píng)論 1 311
  • 那天,我揣著相機(jī)與錄音师骗,去河邊找鬼历等。 笑死,一個(gè)胖子當(dāng)著我的面吹牛辟癌,可吹牛的內(nèi)容都是我干的寒屯。 我是一名探鬼主播,決...
    沈念sama閱讀 40,999評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼黍少,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼寡夹!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起厂置,我...
    開(kāi)封第一講書(shū)人閱讀 39,914評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤菩掏,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后昵济,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體智绸,經(jīng)...
    沈念sama閱讀 46,465評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,543評(píng)論 3 342
  • 正文 我和宋清朗相戀三年砸紊,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了传于。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,675評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡醉顽,死狀恐怖沼溜,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情游添,我是刑警寧澤系草,帶...
    沈念sama閱讀 36,354評(píng)論 5 351
  • 正文 年R本政府宣布通熄,位于F島的核電站,受9級(jí)特大地震影響找都,放射性物質(zhì)發(fā)生泄漏唇辨。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,029評(píng)論 3 335
  • 文/蒙蒙 一能耻、第九天 我趴在偏房一處隱蔽的房頂上張望赏枚。 院中可真熱鬧,春花似錦晓猛、人聲如沸饿幅。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,514評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)栗恩。三九已至,卻和暖如春洪燥,著一層夾襖步出監(jiān)牢的瞬間磕秤,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,616評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工捧韵, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留市咆,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,091評(píng)論 3 378
  • 正文 我出身青樓纫版,卻偏偏與公主長(zhǎng)得像床绪,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子其弊,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,685評(píng)論 2 360

推薦閱讀更多精彩內(nèi)容

  • 1 內(nèi)存尋址 1.1 物理地址癞己、虛擬地址以及線性地址 物理地址: 物理內(nèi)存的內(nèi)存單元地址 虛擬地址: 程序員看到的...
    瘋狂小王子閱讀 2,818評(píng)論 3 21
  • 1. 虛擬存儲(chǔ)器的基本概念 分析常規(guī)存儲(chǔ)器管理不足的原因: 1)常規(guī)存儲(chǔ)器管理方式的特征 一次性:作業(yè)在運(yùn)行前一...
    盆栽木只閱讀 1,327評(píng)論 0 0
  • 概述 我們都知道一個(gè)進(jìn)程是與其他進(jìn)程共享CPU和內(nèi)存資源的。正因如此梭伐,操作系統(tǒng)需要有一套完善的內(nèi)存管理機(jī)制才能防止...
    SylvanasSun閱讀 3,855評(píng)論 0 25
  • 1痹雅、Linux內(nèi)存頁(yè)管理 Linux內(nèi)核管理物理內(nèi)存是通過(guò)分頁(yè)機(jī)制實(shí)現(xiàn)的,它將整個(gè)內(nèi)存劃分成4K大小頁(yè)糊识,作為使分配...
    gbmaotai閱讀 1,418評(píng)論 0 2
  • Swift1> Swift和OC的區(qū)別1.1> Swift沒(méi)有地址/指針的概念1.2> 泛型1.3> 類型嚴(yán)謹(jǐn) 對(duì)...
    cosWriter閱讀 11,113評(píng)論 1 32