1. 程式人生 > >記憶體碎片產生原因及終極解決辦法

記憶體碎片產生原因及終極解決辦法

首先,使用最原始的標記分配方法,系統需要維護一個簡單的記憶體資訊表:

當程式申請一個長度為3的記憶體空間後:

當程式再申請一個長度為2,以及長度為4的記憶體空間後:

此時,只剩1個可用空間。如果這時程式再來申請長度大於1的空間,就申請不了,也就是記憶體不夠。

現在,釋放掉ID=2的空間:

我們發現,現在可用記憶體空間為3,但是,這3個空閒空間,並不是連續的。所以,如果程式現在申請長度為3的記憶體空間,同樣會申請不了,會出現記憶體不夠。業界把這種情況,稱之為【記憶體碎片】。

明明剩餘有3個空間,卻申請不了3個記憶體空間,這TMD扯蛋?

於是,工程師們,發明了基於頁面的記憶體管理方式:

首先,把實體記憶體,按照某種尺寸,進行平均分割。比如我現在以2個記憶體單位,來分割記憶體,也就是每兩個連續的記憶體空間,組成一個記憶體頁:


接著,系統同樣需要維護一個記憶體資訊表:

現在,程式申請長度為3的記憶體空間,不過由於現在申請的最小單位為頁面,而一個頁面的長度為2,因此現在需要申請2個頁面,也就是4個記憶體空間。你看,這就浪費了1個記憶體空間。

接著,程式再申請長度為1,長度為2的空間:


釋放掉ID=2,記憶體頁ID為3的那條記憶體空間資訊:

現在,就出現了之前的情況:目前一共有4個記憶體空間,但是不連續。不過,因為現在是分頁管理機制,因此,現在仍然可以繼續申請長度為4的記憶體空間:

這種方案是不是爽得多?沒有碎片,能夠儘量地全部用完空間。但仔細想想,這種優勢背後,也是需要付出大量代價的。

前面那種記憶體分配方式,雖然容易出現碎片,並且記憶體空間的利用率低,但是使用效能高,程式能直接從記憶體資訊表獲取記憶體地址,接著就可以直接按照地址來使用記憶體空間了。

但下面這種分頁的方式,程式需要記錄的是記憶體頁ID,每次使用時,需要從記憶體頁ID翻譯成實際記憶體地址,多了一次轉換。而且這種模式,會浪費一些記憶體,比如上面申請3個記憶體空間,實際分配了2個頁面共4個記憶體空間,浪費了1個記憶體空間。

以上就是基本原理,實際系統中會做非常多的優化。目前各種主流作業系統都是分頁的方式,因此你不需要太關心碎片。

這個話題再延伸下去,就是一個程式內部的區域性記憶體池了。不過這是另一個問題,喜歡的話可以深究一下。

相關推薦

記憶體碎片產生原因終極解決辦法

首先,使用最原始的標記分配方法,系統需要維護一個簡單的記憶體資訊表: 當程式申請一個長度為3的記憶體空間後: 當程式再申請一個長度為2,以及長度為4的記憶體空間後:此時,只剩1個可用空間。如果這時程式再來申請長度大於1的空間,就申請不了,也就是記憶體不夠。 現在,釋放掉ID=2的空間:我們發現,現在可用記憶體

記憶體碎片產生原因解決辦法

首先,使用最原始的標記分配方法,系統需要維護一個簡單的記憶體資訊表: 當程式申請一個長度為3的記憶體空間後: 當程式再申請一個長度為2,以及長度為4的記憶體空間後:此時,只剩1個可用空間。如果這時程式再來申請長度大於1的空間,就申請不了,也就是記憶體不夠。 現在,釋放掉ID=2的空間:我們發現,現在可用記憶體

記憶體碎片產生原因處理

  記憶體碎片是因為在分配一個記憶體塊後,使之空閒,但不將空閒記憶體歸還給最大記憶體塊而產生的。最後這一步很關鍵。如果記憶體分配程式是有效的,就不能阻止系統分配記憶體塊並使之空閒。即使一個記憶體分配程式不能保證返回的記憶體能與最大記憶體塊相連線(這種方法可以徹底避免記憶體碎片問題),但你可以設法控制並限制記憶

Android OOM產生原因如何解決

OOM產生原因 OOM產生可能的原因是因為 1、載入大圖片導致記憶體溢位 2、大量記憶體洩露 OOM產生的本質是什麼呢? Dalvik VM主要管理的記憶體 Java heap,由於手機裝置的限制,一般一個應用使用的記憶體不能超過預設值 32M(不

HttpURLConnection上傳大檔案記憶體溢位的原因解決辦法

原因: 由於HttpURLConnection預設是有快取機制的,在對檔案操作時,會將讀取的資料寫入到快取區中,並不是直接寫入到伺服器上,只有當流被關閉時,才將資料提交到伺服器上。當快取區的資料大於虛擬機器給點的記憶體時,就導致記憶體溢位。 HttpURLConnectio

SQL Server死鎖產生原因解決辦法

其實所有的死鎖最深層的原因就是一個:資源競爭 表現一:   一個使用者A 訪問表A(鎖住了表A),然後又訪問表B,另一個使用者B 訪問表B(鎖住了表B),然後企圖訪問表A,這時使用者A由於使用者B已經鎖住表B,它必須等待使用者B釋放表B,才能繼續,好了他老人家就只好老老實實

MySql服務未知原因消失了的終極解決辦法

-i study pad data 服務 php user 終極 菜單 剛才突然MySQL-Front打開不了MySql,果不其然發現是MySql的服務不見了。想起可能是昨晚安裝了PhpStudy的點了不要MySql的選項,它把我本身的

移動端1px產生原因解決之道

產生原因     因為Retine屏的解析度始終是普通螢幕的2倍,1px的邊框在devicePixelRatio=2的retina屏下會顯示成2px,所以在高清瓶下看著1px總是感覺變胖了,關於詳細原因介紹參考大漠的文章:http://www.w3cplus.com/css

AJAX跨域產生原因解決方法

什麼是跨域:        跨域問題來源於JavaScript的同源策略,即只有 協議+主機名+埠號 (如存在)相同,則允許相互訪問。也就是說JavaScript只能訪問和操作自己域下的資源,不能訪問和操作其他域下的資源。跨域問題是針對JS和ajax的,html本身沒有跨域問

Linux的殭屍程序產生原因解決方法

來源:http://www.blogdaren.com/post-882.html 1. 產生原因:     在UNIX 系統中,一個程序結束了,但是他的父程序沒有等待(呼叫wait / waitpid)他,那麼他將變成一個殭屍程序。通過ps命令檢視其帶有defunc

各種異常產生原因如何處理解決

異常:nested exception is java.lang.IncompatibleClassChangeError: Implementing class 原因:由於jar包衝突引發的異常。導致不相容。 異常:nested exception is java.la

專案出現記憶體溢位的原因解決方案

記憶體溢位是指應用系統中存在無法回收的記憶體或使用的記憶體過多,最終使得程式執行要用到的記憶體大於虛擬機器能提供的最大記憶體。引起記憶體溢位的原因有很多種,常見的有以下幾種:  1.記憶體中載入的資料量過於龐大,如一次從資料庫取出過多資料;  2.集合類中有對物件的引用,使用

MongoDB 連線數高產生原因解決

MongoDB Sharding架構下連線數很容易達到很高,這裡連線數分為幾個概念: tcp 連線數 netstat可以統計的,一般這個是最高.如果mongod/mongos在同一臺伺服器,更明顯。 參考命令:netstat -ant|awk '{print $5}' |awk -F: '{print $1

記憶體碎片產生原因

     malloc和free大量使用後回造成記憶體碎片,那麼這種碎片形成的機理是什麼?如果機理是申請的記憶體空間大小(太小)所形成的,那麼申請多大的區域能夠最大限度的避免記憶體碎片呢(這裡的避免不是絕對的避免,只是一種概率)?       記憶體碎片一般是由於空閒的連

malloc/free記憶體碎片產生原因

記憶體碎片一般是由於空閒的連續空間比要申請的空間小,導致這些小記憶體塊不能被利用.產生記憶體碎片的方法很簡單,舉個例:          假設有一塊一共有100個單位的連續空閒記憶體空間,範圍是0~99.如果你從中申請一塊記憶體,如10個單位,那麼申請出來的記憶體塊就為0~9區間.這時繼續申請一塊記憶體,比如

C語言野指標的產生原因避免辦法

見如下程式例項:#include <stdio.h> #include <stdlib.h> int main() { char *p1 = NULL; printf("

ajax跨域終極解決辦法

data val 跨域請求 clas 自己 信息 跨域問題 cal header 在使用 ajax 的時候,往往需要通過 ajax 跨域請求一些? 但是 XMLHTTPRequest 是不支持跨域的,所以產生了 JSONP 這個東西來解決跨域,當然解決跨域的方式有很多種..

Eclipse遇到Initializing Java Tooling終極解決辦法

6.5 1.5 ref .exe 一個 ado jre pat -- 轉(http://hi.baidu.com/hz_chenwenbiao/blog/item/7ee57bb3aad17b5a08230269.html) 打開Eclipse時,右下角提升“

Ubuntu 16.04安裝CrossOver容器來安裝QQ(終極解決辦法,親測有效)

bsp 所有 執行 ims class ttf 執行權限 cnblogs helper 註意:此方法能完美解決這篇文章http://www.cnblogs.com/EasonJim/p/7118693.html的所有問題,且不影響現在系統的任何功能,可以說是相當的完美。

Android Studio卡在refreshing gradle project的原因和快速解決辦法

adl 當前 files 成了 span jsb text eas 遇到 這個問題遇到過很多次,網上也有很多解決辦法,但是好像都沒有發現refreshing gradle project在做什麽。 可以再試試 ./gradlew --info 看看詳細信息。 一般refre