matlab管理記憶體方法---解決out of memory
很全的內容,所以整理、方便以後檢視
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
一、利用clear清除記憶體時,要用pack函式進行記憶體整理
Matlab在執行大資料時,會出現Out of Memory,在程式中加入clear不需要的變數,能否解決Out of Memory問題。
答案是或許可以,或許不可以。
原因:清除變數或者給該變數重新賦值只是釋放了該變數先前分配的記憶體塊,由於matlab是分連續塊分配記憶體給變數,所以如果清除的這個記憶體空間不一定可以用上,比如,一個蘿蔔一個坑,為了騰出更多的坑,把不用的蘿蔔拔掉,然而如果來一個比較大的蘿蔔,先前的坑不一定能夠容的下,仍然會出現Out of Memory的問題,這個時候最好用pack函式,把騰出的記憶體空間重新整理成連續的塊,這樣如果後面有較大記憶體佔用的變數,滿足記憶體使用的概率較大。
附pack函式的說明:
用法:
pack
pack filename
pack('filename')
pack可以為使用者整理記憶體的機制在於,pack函式重新整理MATLAB工作空間中駐留的變數,將原來斷斷續續的記憶體整理的連續起來,這樣原來斷斷續續的記憶體可能不足以儲存大的矩陣,而整理之後,可以很顯著的提高記憶體的使用效率。
整理步驟:
(1)將base空間以及全域性變數儲存到一個mat檔案
(2)清空工作空間中的所有資源
(3)重新載入mat檔案中儲存的base空間變數和全域性變數,然後刪掉mat檔案
這樣一來,重新分配的空間將是連續的,避免掉原來斷斷續續的記憶體使用。
注意:pack不能提高MATLAB所擁有的虛擬記憶體數量,如果想要增加這個數量,也就是使MATLAB單獨變數的最大size或者同時存在的變數所佔有的最大空間增大,需要提高系統的虛擬記憶體。
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
二、查詢matlab記憶體使用,計算要處理的資料大小
利用命令feature('memstats')或者system_dependent memstats來檢視記憶體大小;
瞭解自己matlab記憶體狀況後,然後計算下自己要處理的資料容量大小,位元組/1024/1024轉換為MB來看更方便;
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
三、matlab記憶體管理
Matlab 程式跳出“Out of Memory” 時,以下幾點措施是需要優先考慮的解決方法:
1. 升級記憶體
2. 升級64位系統
3. 增加虛擬記憶體
4. 採用3GB開關啟動系統
由於32位 Windows 作業系統的限制,每個程序只能使用最多 2GB 的虛擬記憶體地址空間,因此 Matlab 的可分配記憶體也受到相應的限制。Matlab 7.0.1 引進了新的記憶體管理機制,可以利用 Windows 的 3GB 開關,使用 3GB 開關啟動的 Windows 每個程序可以在多分配 1 GB 的虛擬地址空間。
具體做法是:修改C盤根目錄 boot.ini 啟動選項加上 /3G,
例如:
multi(0)disk(0)rdisk(0)partition(1)\WINDOWS="Microsoft Windows XP Professional" /noexecute=optin /fastdetect /3G
5. 如果必有必要,不要啟動java虛擬機器,採用matlab -nojvm啟動
(在快捷方式屬性裡面的 "..../matlab.exe") 改為("...../matlab.exe" - nojvm)
6. 關閉Matlab Server
控制面板-管理工具-服務, 再找到matlabserver對應項,把啟動型別的自動改為手動即可
matlab server作為後臺服務可以在其它機器上通過網路呼叫此服務,進行計算任務。
7. Windows中字型、視窗等都是要佔用系統資源的,所以在Matlab執行時儘量不要開啟不用的視窗。
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
除此以外,更關鍵的是需要弄清楚以下幾個問題:
問題一:Matlab是如何儲存矩陣的?
Matlab中矩陣是以Block,也就是塊的形式儲存的。也就是說,當Matlab在為即將儲存的矩陣劃分塊時,如果沒有相應大小的連續記憶體,即使實際記憶體沒有被完全使用,它還是會報告“Out of Memory”。
問題二:如何高效實用Memory?
Matlab 中陣列必須佔用連續分配的記憶體段,當無法為新建的陣列分配連續的記憶體段的時候,”Out of Memory” 就會出現。在使用的過程中,由於儲存單元的不斷的被分配和清除,反覆分配和釋放陣列會使記憶體被分割成不連續的區域,可用的連續記憶體段減少,很容易造成“Out of Memory”。因此當 Matlab 剛剛啟動時其連續記憶體最多,此時往往可以新建非常大的陣列,這一點可以用命令feature(’memstats’)(在 7.0 版本以上)看出。如果現實的最大連續記憶體段很小,但實際可用記憶體(非連續的)仍舊很多,則表明記憶體中碎片太多了。此時可以考慮用 pack 命令,pack 命令的作用就是將所有記憶體中的陣列寫入硬碟,然後重新建立這些陣列,以減少記憶體碎片。此外,在命令列或者程式中都可以使用 clear 命令,隨時減少不必要的記憶體。
因此,治本的方法如下:
1. 在命令列輸入 pack 整理記憶體空間
當記憶體被分為很多碎片以後,其實本身可能有很大的空間,只是沒有作構的連續空間即大的Block而已。如果此時Out of Memory,此時使用pack命令可以很好的解決此問題。
2. 使用稀疏矩陣或將矩陣轉化成稀疏形式 sparse
如果矩陣中有大量的0,最好儲存成稀疏形式。稀疏形式的矩陣使用記憶體更少,執行時間更短。例如:
000×1000的矩陣X,它2/3的元素為0,使用兩種儲存方法的比較:
Name X Y
Size 1000x1000 1000x1000
Bytes 8000000 4004000
Class double array double array (sparse)
3. 儘量避免產生大的瞬時變數,把沒必要的變數clear掉或當它們不用的時候應該及時clear。
4. 減少變數,儘量的重複使用變數(跟不用的clear掉一個意思)。
5. 把有用的變數先save,後clear 掉,需要時再讀出來。
下面介紹一下關於clear、save、load的特殊用法,這對在for或while等多重迴圈裡出現out of memory非常有效。
for k = 1:N % N為迴圈次數
% ---------------------
var0 = k; % 獲得變數var0
%----------------------
string = [sprintf('var_%d', k) ' = var0;' ];
eval_r(string); % 等價於 var_k = var0;
save(sprintf('var_%d.mat', k), sprintf('var_%d')); % 等價於 save var_k.mat var_k
clear(sprintf('var_%d')); % 等價於 clear var_k
end
如果要讀取剛才存取的變數var_k, (k = 1,2, ..., N). 那麼,可以使用如下用法:
for k = 1:N
load(sprintf('var_%d.mat', k)); % 等價於 load var_k.mat k = 1,2, ..., N
end
另外,還有一些非常有用的用法。如果用清除剛才讀取的變數 var_k, k = 1, 2, ..., N
clear '-regexp' '^var_' % 清除所有以“ var_ ”開頭的變數
還有很多關於save、clear、load等用法,具體help一下。
6. 使用單精度 single 短整數替代雙精度 double
Matlab 預設的數字型別是雙精度浮點數 (double),每個雙浮點數佔用 8 個位元組。對於一些整數操作來說,使用雙浮點數顯得很浪費。在 Matlab 中可以在預先分配陣列時指定使用的數字型別如以下命令:zero(10, 10, ‘uint8′) 。對於浮點數,在很多精度要求不高的情況下,可以使用4個位元組的單浮點數 (single),可以減少一半的記憶體。關於單、雙浮點數的精度對照如下,以便根據需要選擇使用:
single: 精度 (1.1921e-007) 最大數 (3.4028e+038)
double: 精度 (2.2204e-016) 最大數 (1.7977e+308)
7. 為矩陣變數預製記憶體而不是動態分配
在動態分配的過程中,由於開始Matlab所用的Block隨著矩陣的增大而連續的為此矩陣分配記憶體,但是由於Block的不連續性,很有可能最開始分配的Block不能滿足儲存的需要,Matlab只好移動此Block以找到更大的Block來儲存,這樣在移動的過程中不但佔用了大量的時間,而且很有可能它找不到更大的塊,導致Out of Memory。而當你為矩陣變數預製記憶體時,Matlab會在計算開始前一次性找到最合適的Block,此時就不用為變數連續的分配記憶體。比較下面兩個程式:
for k = 2:1000
x(k) = x(k-1) + 5;
end
x = zeros(1, 1000);
for k = 2:1000
x(k) = x(k-1) + 5;
end
顯然,第二個更好!!!最好的方法是,在程式一開始就位所有大的矩陣變數預製存儲存單元!!!
8. 儘量早的為大的矩陣變數預製記憶體
Matlab使用heap method管理記憶體。當在Matlab heap中沒有足夠的記憶體使用時,它會向系統請求記憶體。但是隻要記憶體碎片可以存下當前的變數,Matlab會重新使用記憶體。比如:
a = rand(1e6,1);
b = rand(1e6,1);
使用大約15.4 MB RAM
c = rand(2.1e6,1);
使用近似16.4 MB RAM
a = rand(1e6,1);
b = rand(1e6,1);
clear
c = rand(2.1e6,1);
使用32.4 MB RAM
Matlab不能使用a、b被clear的空間,因為它們均小於2.1 MB,而同時它們也很可能是不連續的。最好的方法:
c = rand(2.1e6,1);
clear
a = rand(1e6,1);
b = rand(1e6,1);
使用16.4 MB RAM
9. 如果可行的話,將一個大的矩陣劃分為幾個小的矩陣,這樣每一次使用的記憶體減少。
------------------------------------------------------------------------------------------------------------------------------------------------------
分享!
內容整理自很多地方!