目的:為了讓物理內(nèi)存擴充成更大的邏輯內(nèi)存,從而讓程序獲得更多的可用內(nèi)存。一般為物理內(nèi)存的1.5--3倍。
內(nèi)存管理單元(MMU):管理著地址空間和物理內(nèi)存的轉(zhuǎn)換,其中的頁表(Page table)存儲著頁(程序地址空間)和頁框(物理內(nèi)存空間)的映射表。
虛擬地址:分成兩個部分,一部分存儲頁面號,一部分存儲偏移量。
分頁:虛擬內(nèi)存采用的是分頁技術(shù),也就是將地址空間劃分成固定大小的頁,每一頁再與內(nèi)存進行映射。
分段::把每個表分成段,一個段構(gòu)成一個獨立的地址空間。每個段的長度可以不同,并且可以動態(tài)增長。
段頁式:程序的地址空間劃分成多個擁有獨立地址空間的段,每個段上的地址空間劃分成大小相同的頁。這樣既擁有分段系統(tǒng)的共享和保護,又擁有分頁系統(tǒng)的虛擬內(nèi)存功能。
分頁和分段的區(qū)別:
1.對程序員的透明性:分頁透明,但是分段需要程序員顯式劃分每個段。
2.地址空間的維度:分頁是一維地址空間,分段是二維的。
3.大小是否可以改變:頁的大小不可變,段的大小可以動態(tài)改變。
4.出現(xiàn)的原因:分頁主要用于實現(xiàn)虛擬內(nèi)存,從而獲得更大的地址空間;分段主要是為了使程序和數(shù)據(jù)可以被劃分為邏輯上獨立的地址空間并且有助于共享和保護。
頁面置換算法
最近最久未使用(LRU, Least Recently Used):LRU 將最近最久未使用的頁面換出。
- 實現(xiàn)原理:為了實現(xiàn) LRU,需要在內(nèi)存中維護一個所有頁面的鏈表。當(dāng)一個頁面被訪問時,將這個頁面移到鏈表表頭。這樣就能保證鏈表表尾的頁面是最近最久未訪問的。
因為每次訪問都需要更新鏈表,因此這種方式實現(xiàn)的 LRU 代價很高。 -
說明它在 Redis 等作為緩存置換算法。
當(dāng)實際內(nèi)存超出 maxmemory 時,Redis 提供了幾種可選策略 (maxmemory-policy) 來讓用戶自己決定淘汰哪些key。總結(jié)如下:
Redis緩存淘汰策略
當(dāng) Redis 執(zhí)行寫操作時,發(fā)現(xiàn)內(nèi)存超出 maxmemory,就會執(zhí)行一次 LRU 淘汰算法。
Redis 使用的是一種近似 LRU 算法:
1、key增加最近訪問時間戳字段
2、選取一定數(shù)量的key(默認5,server.maxmemory_samples進行配置),比較最近訪問時間。按照LRU算法淘汰key。
注意:maxmemory_samples的值越大,Redis的近似LRU算法就越接近于嚴格LRU算法(隊列結(jié)構(gòu)重排,批量非熱點數(shù)據(jù)緩存垃圾),但是相應(yīng)消耗也變高,對性能有一定影響,樣本值默認為5。
靜態(tài)鏈接和動態(tài)鏈接
1. 編譯系統(tǒng)
- 預(yù)處理階段:處理以 # 開頭的預(yù)處理命令;
- 編譯階段:翻譯成匯編文件;
- 匯編階段:將匯編文件翻譯成可重定位目標文件;
- 鏈接階段:將可重定位目標文件和 printf.o 等單獨預(yù)編譯好的目標文件進行合并,得到最終的可執(zhí)行目標文件。

2. 靜態(tài)鏈接
以一組可重定位目標文件為輸入,生成一個完全鏈接的可執(zhí)行目標文件作為輸出。鏈接器主要完成以下兩個任務(wù):
- 符號解析:每個符號對應(yīng)于一個函數(shù)、一個全局變量或一個靜態(tài)變量,符號解析的目的是將每個符號引用與一個符號定義關(guān)聯(lián)起來。
- 重定位:鏈接器通過把每個符號定義與一個內(nèi)存位置關(guān)聯(lián)起來,然后修改所有對這些符號的引用,使得它們指向這個內(nèi)存位置。
3. 動態(tài)鏈接
靜態(tài)庫有以下兩個問題:
- 當(dāng)靜態(tài)庫更新時那么整個程序都要重新進行鏈接;
- 對于 printf 這種標準函數(shù)庫,如果每個程序都要有代碼,這會極大浪費資源。
共享庫是為了解決靜態(tài)庫的這兩個問題而設(shè)計的,在 Linux 系統(tǒng)中通常用 .so 后綴來表示,Windows 系統(tǒng)上它們被稱為 DLL。它具有以下特點:
- 在給定的文件系統(tǒng)中一個庫只有一個文件,所有引用該庫的可執(zhí)行目標文件都共享這個文件,它不會被復(fù)制到引用它的可執(zhí)行文件中;
- 在內(nèi)存中,一個共享庫的 .text 節(jié)(已編譯程序的機器代碼)的一個副本可以被不同的正在運行的進程共享。
參考:https://blog.csdn.net/Daybreak1209/article/details/82840930
