引言
花了一段時間才把之前的筆記整理了一部分,平時太忙也沒啥時間。今天開始整理記憶體管理部分的,記憶體管理部分大致分為三部分筆記,第一部分就是本篇記憶體管理基礎,第二部分是虛擬記憶體,第三部分快取記憶體。
乙個程式在執行前,只是乙個儲存在磁碟上的可執行的二進位制檔案,包括可執行指令和資料。當程式執行時,這個二進位制檔案會被載入到記憶體中,指令和資料在執行時會被cpu從記憶體中載入到暫存器中,然後執行,可能會把執行結果再次存入記憶體中。資料以何種形式存在記憶體,如果為程序分配記憶體,程序退出如何**,這個過程叫記憶體管理,接下來就詳細介紹這個過程
早期無儲存器抽象
無儲存器抽象記憶體訪問
使用者程式直接操作物理記憶體的位址,比如將位置為1000的物理記憶體中的內容複製到register1
mov register1,1000
物理記憶體模型
多個程式執行-物理分塊記憶體
儲存抽象-位址空間
前邊已經知道了無儲存抽象,也就是直接使用物理記憶體的兩個缺點
哪怕只有乙個應用程式執行,作業系統記憶體也可能會被偶然或惡意破壞
多應用程式併發執行困難
位址空間概念
如果記憶體足夠大到可以容納所有程序的**和資料,那麼位址空間加上硬體提供的動態重定位的方案或許已經可行,但是通常所有程序需要的記憶體超過儲存可以提供的範圍。
1. 通過軟體在載入的時候重定位
2. 通過硬體在執行的時候重定位(比較常用),基位址和界限暫存器就適用這種情況
記憶體壓縮
記憶體因為程序的換入換出會產生一些記憶體空洞,這些記憶體空洞會導致記憶體浪費,因為這些空洞連續記憶體空間大小不足以容納乙個程序所需的空間。因此通過將所有程序占用的空間全部向下移動,就有可能將小的空洞連成一大塊空閒記憶體。這種技術就叫記憶體壓縮
程序記憶體大小分配問題
1. 固定大小,如果程序大小是固定不會改變,作業系統只需簡單分配程序需要的大小
2. 資料段可能增長,此時有四種解決方法
1. 如果程序鄰近有空閒記憶體,分配給程序
2. 如果程序鄰近是其他程序,那麼尋找一塊更大的空閒記憶體,將程序遷移過去
3. 如果沒有更大的空閒記憶體,那麼嘗試將鄰近的程序交換出去
4. 如果程序無法增長記憶體並且交換區已經滿了,那就掛起該程序直到有空閒記憶體(或者kill該程序)
為了提高記憶體分配的效率,滿足大部分程序記憶體都會增長的場景。(a)系統在分配記憶體時為程序預留增長所需的空間;(b)如果程序有連個可增長的段,比如資料段和棧段,可以資料段從下往上分配,棧從上往下分配,如果記憶體不足時再增長記憶體。
針對虛擬記憶體的,在下一部分詳細介紹
空閒記憶體管理
空閒鍊錶
1. a中x釋放後,空閒鍊錶p替換為h,該空間空閒
2. b和c的x釋放後,兩個相鄰的空閒區域合併成乙個區域,鍊錶變短
3. d中x釋放後三個鍊錶節點合併成乙個
連續記憶體分配演算法
截止目前我們討論的記憶體都是將記憶體作為連續記憶體為基礎的,連續記憶體指的是我們分配給程序的內存在空間上是連續的,在下一部分中會介紹虛擬記憶體,將會看到,程序是可以被分配不連續的記憶體。拿上邊圖中的空閒鍊錶做例子
QT應用程式單例項執行
我們經常會做一些軟體 程式只希望有最多乙個執行例項。我從網上找到了個方法,雖然現在還不太明白原理,但是這種方法總算會用了。原文摘自 int main int argc,char argv if sharemem create 1 return 0 當然別忘了在開頭加上 include 這段 應該不用...
QT開發應用程式(13) 資料庫操作
在工程中新增定義 qt sql 標頭檔案定義 include class mydatabase mydatabase函式實現 void mydatabase connectmysql else 未連線則新建資料庫連線if database.open 建立資料庫 資料表 建立資料庫 資料表 void ...
QT開發應用程式(18) 檔案操作
直接繼承自qobject,是輸入 輸出裝置的抽象類。提供了公共實現和抽象介面用於讀寫塊資料。q3socket,q3socketdevice,qabstractsocket,qbuffer,qfile,qlocalsocket,qnetworkreply,qprocess是它的子類。開啟檔案 bool...