2010-07-21 32 views
10

Tôi gặp một số vấn đề với quản lý bộ nhớ trong Matlab. Cuối cùng nó dẫn đến không đủ bộ nhớ miễn phí và một error.I đã cố gắng xác định vấn đề và tìm thấy một "tính năng" thú vị: Bằng cách nào đó tôi mất bộ nhớ miễn phí trong Matlab.Matlab: Mất bộ nhớ miễn phí sau khi gọi hàm

tôi làm như sau:
1) Bắt đầu Matlab
2) gõ "bộ nhớ" Tôi nhận được: mảng có thể tối đa: 1293 mb, bộ nhớ có sẵn cho tất cả các mảng: 1456 mb
3) Tôi sẽ gọi một chức năng. Hàm này khá dài, do đó rất khó để dán nó ở đây. Nhưng về cơ bản nó tải 5 ca. Các tệp mat 300mb (tuần tự), chọn một vài giá trị và trả về chúng. Ma trận trả về là ca. 1,2mb (4650x35 đôi)
4) Tôi xóa tất cả các biến trong không gian làm việc ("xóa tất cả")
5) nhập "bộ nhớ" tôi nhận được: Mảng tối đa có thể: 759 mb, Bộ nhớ có sẵn cho tất cả các mảng: 1029 mb

Nếu tôi lặp lại các bước 3) đến 5), số bộ nhớ là không đổi.

Vậy có gì sai ở đây? Tôi mất 400mb dung lượng trống ở đâu? Bộ nhớ được sử dụng bởi Matlab là không đổi ở khoảng 330mb.

Có ai có ý tưởng gì sai ở đây không? Hoặc là cái gì đó hoàn toàn tự nhiên, nhưng tôi nhớ nó?

Cảm ơn
Thomas

Ps: Tôi sử dụng Matlab 2010a và Win 7 32bit pro.

Trả lời

16

Một phần tốt của bộ nhớ "bị mất" này có thể do phân mảnh bộ nhớ. Khi Matlab phân bổ và giải phóng các mảng trong suốt một phiên, bộ nhớ bị chia nhỏ thành các vùng nhỏ hơn, và một số bị mất trên đầu trong bộ quản lý bộ nhớ, ở cả mức Matlab và C bên dưới. Chi phí trên không được tính là "được sử dụng" bởi Matlab vì nó không được sử dụng để giữ các giá trị mảng M-mã. Một số bộ nhớ cũng có thể được Matlab tiêu thụ tải thêm các tệp M và thư viện, phân bổ bộ đệm hoặc cấu trúc bên trong hoặc bằng cách mở rộng vùng heap Java trong JVM được nhúng của Matlab. Điều này là bình thường. Sau khi thực hiện một số công việc, Matlab sẽ không có nhiều bộ nhớ như đã làm trong một phiên mới.

AFAIK, khi phân đoạn cấp thấp xảy ra, bạn không thể làm gì để loại bỏ nó ngoài việc khởi động lại Matlab. Phân bổ rất nhiều mảng nhỏ có thể đẩy nhanh phân mảnh. Điều này đôi khi xảy ra nếu bạn sử dụng cellstrs lớn hoặc mảng lớn của các đối tượng. Vì vậy, nếu bạn gặp sự cố, bạn có thể cần giảm mức sử dụng bộ nhớ cao nhất của mình trong chức năng bằng cách chia nhỏ công việc thành các phần nhỏ hơn, giảm mức sử dụng ô, v.v. Và nếu bạn có các mảng cellstr lớn trong các tệp MAT, hãy chuyển chúng thành char. "Phân bổ nước cao" của phân bổ là những gì điều chỉnh phân mảnh, vì vậy nếu bạn có thể phá vỡ dữ liệu của bạn đặt thành các phần nhỏ hơn, bạn có thể phù hợp với nó trong bộ nhớ ít hơn.

Bên trong chức năng của bạn, xóa nhiều nhất có thể từ một tệp MAT trước khi chuyển sang bước tiếp theo. Một cách để làm điều này ngầm là di chuyển xử lý mỗi tệp vào một hàm phụ nếu nó hiện đang nằm trong một vòng lặp trong hàm chính của bạn.

Để giúp gỡ lỗi, hãy thực hiện "dbstop nếu tất cả lỗi", sẽ được kích hoạt bởi OOM. Từ đó, bạn có thể sử dụng whos và trình gỡ lỗi để tìm ra nơi mà không gian được lấy lên khi bạn xả bộ nhớ. Điều đó có thể tiết lộ các biến tạm thời cần phải được làm sạch hoặc đề xuất các cách chunking công việc.

Nếu bạn muốn thử nghiệm xem phân mảnh trông như thế nào và nó ảnh hưởng như thế nào đến đầu ra của bộ nhớ(), đây là một hàm sẽ tạo ra một số phân mảnh.

function fragmem(nbytes, chunksize) 
%FRAGMEM Fragment the Matlab session's memory 
if nargin < 2; chunksize = 1*2^10; end 

nbytes = nbytes - rem(nbytes, chunksize); 

nsteps = 100; % to make initial input relatively small 
c = cell([1 nsteps]); 
stepsize = nbytes/nsteps; 
chunksperstep = ceil(stepsize/chunksize); 
fprintf('Fragmenting %d MB memory into %d KB chunks (%d steps of %d chunks)\n',... 
    round(nbytes/2^20), round(chunksize/2^10), nsteps, chunksperstep); 

x = zeros([1 chunksperstep * chunksize], 'uint8'); 
colsizes = repmat(chunksize, [1 chunksperstep]); 
for i = 1:nsteps 
    c{i} = mat2cell(x, 1, colsizes); 
end 

Mảnh 300 MB trong khối 1KB trên máy của tôi tạo lại "mất mát" trên máy win32 của tôi về kích thước bạn đang thấy.

>> memory 
Maximum possible array:   1384 MB (1.451e+009 bytes) * 
Memory available for all arrays: 1552 MB (1.627e+009 bytes) ** 
Memory used by MATLAB:    235 MB (2.463e+008 bytes) 
Physical Memory (RAM):    3311 MB (3.472e+009 bytes) 

>> fragmem(300*2^20) 
Fragmenting 300 MB memory into 1 KB chunks (100 steps of 3072 chunks) 
>> memory 
Maximum possible array:   1009 MB (1.059e+009 bytes) * 
Memory available for all arrays: 1175 MB (1.232e+009 bytes) ** 
Memory used by MATLAB:    257 MB (2.691e+008 bytes) 
Physical Memory (RAM):    3311 MB (3.472e+009 bytes) 

>> 
+0

+1 bạn đã cố gắng gọi 'pack' sau http://www.mathworks.com/access/helpdesk/help/techdoc/ref/pack.html – Amro

+2

Pack() chỉ sắp xếp lại mảng Matlab có hiện được phân bổ. Nó không giải quyết sự phân mảnh cấp thấp hơn này do dư lượng của các mảng đã giải phóng, và có hiệu ứng không đáng kể sau ví dụ fragmem(). (Ít nhất là trên Windows, mà tôi sử dụng.) BTW, docl Matlab thực sự không nói về phân mảnh cấp thấp hơn này; những gì tôi đang viết, tôi đã suy ra từ tài liệu Giao diện bên ngoài và thử nghiệm với Matlab và C. Caveat emptor. –

+0

"Để giúp gỡ lỗi, hãy thực hiện" dbstop nếu tất cả các lỗi ", do OOM kích hoạt. Từ đó, bạn có thể sử dụng trình gỡ lỗi và trình gỡ lỗi để tìm ra nơi không gian được lấy khi bạn xả bộ nhớ. tiết lộ các biến tạm thời cần được làm sạch hoặc đề xuất các cách chunking công việc. " Điều thú vị là không gian làm việc sạch sẽ khi tôi hết bộ nhớ. Chức năng trên thực sự làm giảm bộ nhớ miễn phí, nhưng không có nhiều vars trong không gian làm việc ... Đó là loại gây phiền nhiễu có đủ RAM..in nguyên tắc .. – Thomas

Các vấn đề liên quan