2010-03-05 3 views
15

핸들의 서브 클래스로 객체를 선언하면 classdef obj < 핸들 내 객체가 이제 어딘가에있는 일부 메모리의 "포인터"가됩니다. 객체가 얼마나 많은 메모리를 사용하고 있는지 어떻게 알 수 있습니까? 예를 들어 핸들 객체가 matlab에서 사용하는 메모리 용량을 어떻게 알 수 있습니까?

, 나는

classdef foo < handle 
properties 
    bar = randn(1000); 
end 

바 8 메가 바이트 (8 바이트 * 1 개 백만 번호)

을 차지 필드 바 클래스 foo는이 말을하지만 난

obj = foo(); 
whos('obj'); 
를 입력하면

얻을 수 있습니다.

Name  Size   Bytes Class Attributes 

    obj  1x1    60 foo     

얼마나 많은 총 메모리 obj가 가리키는 지 어떻게 알 수 있습니까?

답변

11

해킹으로 구조체로 변환하고 차지하는 공간을 확인하십시오. 나는 그것이 "일반"객체 필드에 모든 데이터를 노출 할 것이라고 생각합니다.

f = foo(); 
origWarn = warning(); 
warning off 'MATLAB:structOnObject' 
s = builtin('struct', f); % use 'builtin' in case @foo overrides struct() 
warning(origWarn); 

그러면 whos에서 볼 수 있습니다.

>> whos 
    Name  Size    Bytes Class  Attributes 

    f   1x1     60 foo     
    s   1x1    8000124 struct  

이것은 단지 일차 근사치입니다. 해당 필드가 사용하는 메모리 양을 알려줍니다. 그들 중 하나가 핸들 객체를 포함하고 있다면, 그 구조체의 필드를 되풀이하여 다른 필드를 계산하기 위해 다른 핸들 객체를 struct로 변환해야합니다. (Java 객체의 메모리를 포함 시키려면 저장소 크기를 계산하는 별도의 함수가 필요합니다. 아마도 신경 쓰지 않아도됩니다.) 이제 Matlab에 클로저가 있고 함수 핸들에 데이터가 포함될 수 있습니다. 클로즈 오버 (closed-over) 데이터를 계산하려면 함수()를 사용하여 펀치 할 필요가 있습니다.

핸들 객체로 작업하는 경우 M 코드 수준에서 앨리어싱 및 순환 참조가있을 수 있으므로 재귀 할 때이를 참고해야합니다. (죄송합니다, 새로운 OO 시스템에서 어떻게 처리해야할지 모르겠다.)

메모리 디스플레이는 Matlab의 copy-on-write 최적화를 통해 메모리를 공유하는 어레이를 두 배 계산한다. 여기에 구체적인 예가 있습니다.

x = NaN(1,10000); 
s.x = x; 
s.y = x; 
s.z = x; 


>> whos 
    Name  Size    Bytes Class  Attributes 

    s   1x1    240372 struct    
    x   1x10000    80000 double    

사실상 s는 약 80K 만 소모합니다. x에 3 개의 포인터가 있습니다. 80K는 x 자체가 소비하는 80K와 같습니다. 그들 중 하나를 수정하지 않으면; 새로운 배열이 할당된다. Whos()는 해당 사례를 차별화하지 않습니다. 이것을 처리하는 것은 어렵습니다. AFAIK를 사용하는 유일한 방법은 MEX 파일을 사용하여 mxarray의 데이터 포인터를 가져 와서 개체 트리를 직접 걷고 별칭이 지정된 포인터를 검색하고 별칭이 지정된 바이트를 계산하는 것입니다.

이것은 구성 요소를 공유 할 수있을 때 메모리에있는 개체의 크기를 측정 할 때 일반적으로 발생하는 문제입니다. 이산 물체가 아닙니다. 최소한 C에서는 임의의 메모리 블록에 대한 포인터를 가지고 작업하고 있습니다.

+0

감사합니다! 정말 좋은 제안입니다. 한 가지 질문은 matlab가 새로운 메모리와 복사를 할당하는 방법을 이해하지 못하기 때문입니다. foo에서 struct로 변환하는 데 얼마나 많은 메모리가 필요합니까? 즉, foo가 1GB 필드를 가지고 있다면 구조체로 변환하면 MATLAB이 여분의 GB 메모리를 소비하게됩니까? – Marc

+0

Java 객체의 크기를 어떻게 예측 하시겠습니까? - 이들은 Matlab에서 0 바이트를 가진 것으로보고됩니다 ... –

+0

@Marc : foo를 구조체로 변환하면 많은 메모리가 사용되지 않습니다. 그냥 구조체 자체가 변환됩니다. 그 가상의 1GB 필드를 포함하여 구조체 필드의 내용은 matlab의 copy-on-write 최적화를 사용하여 각각 공유됩니다. –

2

방금 ​​발견 한 쉬운 방법은 Dmitry Borovoy입니다. here입니다. 나는 그것을 여기에서 이용할 수있게하고 싶었다.

모든 속성에서 데이터를 수집하는 메서드를 제공하는 기본 클래스에서 클래스를 파생시킵니다. 위의 링크에서 코드를 가져옵니다.

function total_mem = get_mem(obj) 
     %// Get all properties 
     props = properties(obj); 

     total_mem = 0; 
     %// Loop properties 
     for ii=1:length(props) 
      %// Make shallow copy 
      curr_prop = obj.(props{ii}); %#ok<*NASGU> 
      %// Get info struct for current property 
      s = whos('curr_prop'); 
      %// Add to total memory consumption 
      total_mem = total_mem + s.bytes; 
     end 
    end 

샘플 사용 :

>> fprintf('%.1f MB in use.\n',do.sde.get_mem/1024^2) 
7413.0 MB in use. 
+0

이 방법은 재귀 또는 중첩 핸들에서는 작동하지 않지만 좋은 제안이라고 생각합니다. – Marc

관련 문제