2012-04-09 2 views
2

어레이 메모리의 일부를 시스템에 반환하는 효과적인 방법이 있습니까? C#을 사용하여 하나의 큰 문자열 배열과 해시 테이블 (> 100k 요소)을 반복하고 각 요소를 끝내면 null로 설정합니다. 가베지 수집기를 다양한 수준에서 루프를 통해 호출하는 실험을 해봤지만 시스템 전체에 메모리를 반환하는 사람은 아무도 없습니다 (가비지 수집기를 완전히 호출하고 대기중인 종료자를 기다리면 코드가 매우 느리고 반응이 느려집니다).
나는 각 부분이 완료된 후 GC를 n 개의 부분으로 배열을 분할 및 통화에 대해 생각했지만 그점차적 인 GC 호출

GC.Collect(1); 
GC.Collect(2); 
.... 
GC.Collect(); 
GC.WaitForPendingFinalizers(); 
GC.Collect(); 
+4

아마도 가장 좋은 방법은 GC가 그 일을하도록하는 것입니다. null에 대한 참조 설정이 충분하지 않습니다. –

+0

@HenkHolterman ok :) 나는 물어 보지 않을 것 같았다. 만약 내가 어떤 대답을 얻지 못하면 나는 질문을 지울 것이다. –

+1

개체에 대한 다른 살아있는 참조가 없다고 가정한다. 또한 충분히 큰 경우 큰 오브젝트 힙에 할당 될 수 있으며 조각화를 볼 수 있습니다. –

답변

2

그냥 가비지 컬렉터가 일을 할 수 있도록 지저분한 것 같다. 가장 효율적인 접근법은 GC가 이미 수행하는 작업입니다. 컬렉션을 실제로 완료해야 할 때까지 연기합니다. 그렇게하면 필요한 것보다 더 많은 콜렉션을 수행 할 필요가 없으며 모든 메모리 재생 작업을 비교적 적은 콜렉션 호출로 일괄 처리 할 수 ​​있기 때문에 필요한 것보다 오브젝트 그래프를 더 자주 횡단 할 필요가 없습니다.

그냥 객체에 대한 참조를 취소해야합니다, 그래서 필요 이상으로 당신은 실수로 이제 생존을 유지하지 않지만만큼 당신이 그렇게, 당신은 정말 다른 작업을 수행 할 필요가 없습니다. 모든하지만 매우 특수하고 예외적 인 상황에서

0

은 최선의 정책은 가비지 컬렉터가 자신의 일정에 따라 작동 할 수 있도록하는 것입니다. 그것은 당신이나 내가 가지고있는 것보다 CLR의 내부 동작에 대한 지식이 훨씬 많은 고도로 조정 된 소프트웨어입니다. 거의 항상 우리보다 더 나은 결정을 내릴 것입니다.

작업을 완료 한 후에 객체가 소비하는 메모리가 염려되는 경우 작업을 마칠 때 개별 배열 요소를 null로 설정할 수 있습니다 (잠재적으로 객체를 더 빨리 수집 할 수있게 만들 수 있음).

점에 더, 한 번에 메모리에 모든 데이터를 유지 할 필요가있다? 한 번에 조금만로드 할 수 있습니까 - 예를 들어 파일에서 점진적으로 읽으려면? 그렇다면 어레이를 IEnumerable<T>으로 교체 할 수있는 옵션이 있습니다. 필요에 따라 데이터를 지연로드 할 수 있으며 데이터 처리가 완료되면 자동으로 잊어 버릴 수 있습니다. 이 접근법은 약간의 추가 계산을 희생시키면서 메모리 소비를 억제합니다.

0

문자열을 배열에 저장하면 문자열을 반복하는 동안 문자열을 모두 메모리에 유지합니다.

실제 반복 메모리 압력을 많이 증가하지 않습니다 : 당신이 효율적으로 쓰레기가 수집됩니다 새로 만든 객체. 당신이 그들을 읽고 나면

배열의 특정한 경우를 들어, null에 배열 항목을 설정할 수 있습니다. 내가 반대하는 것이 좋습니다 : 만약 당신이 기억의 문제없이 반복의 시작에서 살아남는다면, 당신은 아마도 나머지에서도 살아남을 것입니다. 이 더 이상 필요 없으면 배열에 대한 참조가 null인지 확인하십시오. 디버깅하는 동안 배열이 더 이상 참조되지 않는 시점에 GC.Collect()를 추가 할 수 있습니다. 할당 된 메모리가 크게 떨어지는 것을 관찰해야합니다. 이것이 발생하지 않으면 배열에 대한 참조 또는 배열 내용에 대한 참조가 다른 곳에 있습니다.

해시 테이블의 경우이 방법은 전혀 작동하지 않습니다. 해시 테이블을 반복하면서 항목을 안전하게 제거 할 수는 없습니다. 당신이 해시 테이블을 사용하는 경우

지금, 이것은 당신이 항목의 순서에 관심 정말하지 않는 것을 의미한다.이 경우 배열이나 해시 테이블에 데이터를 보관하지 않고 데이터를 읽을 때 알고리즘을 처리하여 알고리즘을 처리 할 수 ​​있습니다.