MATLAB學習之內存溢出的管理方法


今天用Matlab跑程序,由於數據量太大,又出現 Out of memory. Type HELP MEMORY for your options.的問題。看到這篇文章非常實用,轉過來方便查閱~

用 Matlab 進行大規模科學計算或仿真時,內存是一個需要時常注意的問題。在matlab里運行

>>system_dependent memstats

就可以看到內存的使用狀況。當你寫的 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
Size
Bytes
Class

X
1000x1000
8000000
double array

Y
1000x1000
4004000
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. 如果可行的話,將一個大的矩陣划分為幾個小的矩陣,這樣每一次使用的內存減少。

經過保存需要的變量,刪除不必要的變量,運行pack命令,系統前后的內存占用情況有了很大改善:

這是清理之前:

>> memory
Maximum possible array:              15 MB (1.622e+007 bytes) *
Memory available for all arrays:    194 MB (2.036e+008 bytes) **
Memory used by MATLAB:             1549 MB (1.624e+009 bytes)
Physical Memory (RAM):             4095 MB (4.294e+009 bytes)

*  Limited by contiguous virtual address space available.
** Limited by virtual address space available.

這是清理之后:

Maximum possible array:             252 MB (2.641e+008 bytes) *
Memory available for all arrays:    988 MB (1.036e+009 bytes) **
Memory used by MATLAB:              762 MB (7.991e+008 bytes)
Physical Memory (RAM):             4095 MB (4.294e+009 bytes)

*  Limited by contiguous virtual address space available.
** Limited by virtual address space available.

 

文章轉自:http://hi.baidu.com/flyingsnow0102/blog/item/98266c1955b512f5ae51331b.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM