2011-11-19 3 views
2

나는 바이너리 파일 크기 15킬로바이트의 디스크 만에 저장할 수있는 메모리의 크기는 항상 4 바이트 만GC.GetTotalMemory 사용 및 반환 값

long mem1=GC.GetTotalMemory(false); 
Object[] array= new Object[1000000]; 
array[1]=obj; // obj is the object content of the file before it is saved on disk 
long mem2=GC.GetTotalMemory(false); 
long sizeOfOneElementInArray=(mem2-mem1)/1000000; 

어디 선가 뭔가 잘못입니다 이유. 나는 4 바이트가 hello world 문자열을 저장하기에 충분하지 않기 때문에 그것이 틀렸다고 생각한다. 그러나 왜 틀린가? 도움 주셔서 감사합니다. 일반적으로

+0

디스크의 파일과 어떤 관련이 있습니까? –

+0

오브젝트가 디스크에 바이너리 파일로 저장되기 전에 obj가 얼마나 많은 메모리를 소비하는지 보려고하는 오브젝트입니다. 4 바이트입니다. 메모리 사용량을 검색하는 방법에 대해 내가 맞다고 생각합니까? – PointedC

+0

@PointedC, 당신이 가지고있는 코드는'obj'를 전혀 측정하지 않습니다. 'o'만 측정합니다. – svick

답변

1

, MSDN documentation가 정확한 값에 의존하는 나쁜 생각 현재 관리되는 메모리에 할당 된 바이트의 수량에 대한 최선의 근사하는 숫자입니다 :-) 같은 것들을 말한다

'o'가 예제에서 3 번째 줄 이후 함수에 사용되지 않으면 3 번째 줄과 4 번째 줄 사이에 개체가 수집 될 수 있습니다.

2

배열의 인덱스 [1]에 obj를 할당하면 상당한 바이트 수를 차지한다는 가정이 있습니까? 당신이하는 일은 참조를 지정하는 것뿐입니다. 그뿐 아니라, new Object[1000000]은 배열 (1,000,000 개의 Object와 필요한 메모리를 연결하는 공간, Object[]이 필요합니다.)을 만들고, 1,000,000 개의 Object를 할당하지 않았습니다. 나는 누군가가 내부 데이터 구조에 대해 더 자세히 설명 할 수 있고 4 바이트가 왜 나타나는지 확신한다.

실현해야 할 핵심 사항은 obj에서 o[1]obj에 대한 추가 메모리를 할당하지 않는다는 것입니다. 대략 GC.GetTotalMemoryobj이 할당되기 전에 결정하려고하면 다음에 나온 것입니다. o가 할당 후 사용되지 않는, 그래서 GC가 수집 할 수 있기 때문에 첫 번째 GC.GetTotalMemory

+0

4 바이트는 32 비트 아키텍처에서 참조 (포인터)의 크기입니다. – svick

+0

+1. 예, 질문의 코드는 특정 플랫폼 (x86은 VS 2010의 기본값 임)에서 개체 참조의 크기가 4 바이트임을 확인합니다. –

1

먼저 호출하기 전에 내가 작성된 코드를 사용하는 경우 테스트에서 obj 이미 할당 x는, 나를 위해 0이된다. 다음은 o이 수집되지 않은 것으로 가정합니다 (예 : 메소드 마지막에 GC.KeepAlive(o) 사용).

의이 코드의 중요한 두 라인의 각 (32 비트 아키텍처를 가정) 할주의 깊게 무엇을 살펴 보자 :

Object[] o = new Object[1000000]; 

이 줄은 1,000,000 * 4 + 16 바이트를 할당합니다. 배열의 각 요소는 객체에 대한 참조 (포인터)이기 때문에 4 바이트를 사용합니다. 16 바이트는 배열의 오버 헤드입니다.

o[1] = obj; 

이 줄 obj하여 참조하도록 o에서 참조 하나 바꾼다. 이 행은 정확히 0 바이트를 할당합니다.

결과에 대해 혼란 스러울 지 모르겠습니다. 코드의 앞 부분에있는 참조되지 않은 객체가 없으면 4가되어야합니다. 이 경우 4보다 작을 수 있습니다 (음수 일 수도 있음). 물론 이것이 멀티 스레드 응용 프로그램이라면 다른 스레드가 수행하는 작업에 따라 결과가 거의 달라질 수 있습니다.

그리고이 모든 것은 GetTotalMemory()이 정확하다고 가정합니다.

-1

제 경험상 가비지 수집기에 문의하는 것보다 일반적으로 marshal.sizeof()이 개체의 실제 크기를 가져 오는 더 좋은 방법입니다.

http://msdn.microsoft.com/en-us/library/y3ybkfb3.aspx

+0

'Marshal.SizeOf()'는 masrshaled 형태의 객체 크기를 얻기위한 것으로, 보통 크기와 같을 필요는 없습니다. (나는'GetTotalMemory()'가 그것을하는 올바른 방법이라고 말하지 않고있다. 그러나 Marshal.SizeOf()는 분명히 그렇지 않다.) – svick