2011-02-04 2 views
3

.NET App에서 메모리 누수를 추적하려고합니다. Windows 작업 관리자는 메모리 사용량이 지속적으로보고하는 반면 Process Explorer은 메모리 사용량이 증가한다고보고합니다. 작업 관리자에서 작업 관리자가 Process Explorer와 일치하지 않습니까?

, 나는 전용 메모리 칼럼, "메모리 (개인 작업 집합)"에서 찾고 있어요. Process Explorer에서 "Private bytes"열을 찾고 있는데, 그 이유는 "Working set"아래의 값이 올라 가기 때문입니다.

몇 가지 할당 후에 내 응용 프로그램이 메모리 부족 ( 예외)으로 인해 프로세스 탐색기가 적합합니다. 문제는 왜 작업 관리자 앱의 메모리 사용을 잘못보고 않습니다입니까? 뿐만 아니라 글로벌 시스템의 여유 메모리를 잘못보고합니다 (성능 탭의 그래프는 일정하게 유지됩니다).

내 코드가 필요하지 않을해야하지만, 여기가 완전성을위한 것입니다. 큰 배열을 포함하는 빈 창을 보여줍니다. 아무 키나 누르면 창이 닫히고 새 배열이 열리고 새 창이 열립니다. 이전 창은 qt4dotnet GUI 라이브러리의 버그로 인해 누출되었습니다.

using System; 
using com.trolltech.qt.gui; 

namespace LeakTest 
{ 
    class Test : QWidget 
    { 
     public byte[] Data = new byte[1000 * 1000 * 100]; 

     public Test() 
     { 
      show(); 
      GC.Collect(); // so measurements are more accurate 
     } 

     protected override void keyPressEvent(QKeyEvent arg__1) 
     { 
      disposeLater(); 
      new Test(); 
     } 

     [STAThread] 
     static void Main(string[] args) 
     { 
      QApplication.initialize(args); 

      new Test(); 

      QApplication.exec(); 
     } 
    } 
} 

OS : 윈도우 7

재미있는 참고 : 나는 "데이터"차원 [1000 * 1000 * 100][1]의 2D 가변 배열, 작업 관리자 을 할 때 않는 메모리 사용량을 제기 보고서.

+1

.NET 메모리 누수를 찾기 위해 작업 관리자/프로세스 탐색기를 사용하는 것에 강하게 반대 할 것입니다.Ususally, 나는 [ANTS Memory Profiler] (http://www.red-gate.com/products/dotnet-development/ants-memory-profiler/)를 사용하고 심지어 그러한 특수한 도구로도 누설을 찾기가 어렵다. . 방금 작업 관리자를 사용했다면 나는 과거에 누수를 발견 할 기회가 없었을 것입니다. –

+1

아직 사용 된 적이없는 페이지는 첫 번째 액세스시에만 0으로 지정할 수 있기 때문에 백킹이 필요하지 않습니다. 따라서 그들은 개인용 바이트로 간주하지만 RAM이 필요없고 작업 세트의 일부가 아닙니다. – CodesInChaos

+0

@CodeInChaos : 아, 그게 많이 설명됩니다. –

답변

6

그들은 두 개의 완전히 다른 메모리 조치입니다. 작업 집합은 프로그램에서 사용하는 RAM의 양입니다. 이는 지속적으로 변화하는 숫자이며 다른 프로세스에 필요한 RAM 용량에 영향을받습니다. RAM이 부족할 수 없기 때문에 Windows는 매핑 된 페이지를 페이징 파일로 스와핑하여 RAM을 사용할 수있게합니다.

개인 바이트는 다른 프로세스와 공유하지 않는 프로그램에서 사용하는 가상 메모리의 양입니다. 32 비트 컴퓨터에서는 2 기가 바이트의 가상 메모리를 사용할 수 있습니다. 코드와 데이터간에 공유해야합니다. 요청 된 할당에 맞게 가상 메모리의 주소 지정 가능한 양에 충분한 공간이 남아 있지 않으면 OOM을 얻습니다. 예, 정확한 숫자입니다.

한 번에 1백메가바이트에 대한 요구는 위험합니다. 가상 메모리 공간은 단편화 될 수 있으며 잠시 후에는 여전히 많은 가상 메모리가 있지만 100MB에 달할만큼 큰 구멍은 아닙니다. 가변 배열은 배열의 배열이기 때문에이 문제를 해결합니다. 필요한 청크는 훨씬 작아서 어떤 구멍이 남든간에 쉽게 맞출 수 있습니다.

64 비트 운영 시스템이 문제를 완전히 해결할 수있다. 프로그램의 주소 공간은 기가 바이트이며 실제로는 페이징 파일의 최대 크기로 제한됩니다. 당신은 단순히 큰 구멍을 다 쓸 수 없습니다.

1

메모리 누수를 추적하고 코드를 읽어서 찾을 수 없으면 작업을 위해 설계된 실제 도구가 필요할 것입니다.

작업 관리자 나 프로세스 탐색기는 메모리 누수를 디버깅하는 데 적절한 도구가 아닙니다. 반환되지 않는 메모리를 할당 할 위치를 알려주는 것이 좋습니다.

+1

예, 메모리 프로파일 러 :-) –

+1

@ 정말요! 물론 .net과 같은 GC 시스템에서도 훌륭한 도구를 사용하더라도 추적 할 수 있습니다. –

+0

@Uwe Keim : 예, 실제로 dotTrace 메모리 프로파일 러를 실제로 사용하고 있었지만 .NET에서 C++ 라이브러리에 Java 바인딩을 사용하고 있기 때문에 실제로 어떤 것이 있는지 알 수 없었습니다. 그래서 나는 먼저 프로파일 러없이 가능한 많은 것을 이해하려고 노력했습니다. 그리고 나는 이런 종류의 설명 할 수없는 행동을 발견 했으므로 나는 그 질문을 게시했다. 아마도 프로파일 러에 대한 또 다른 질문을 게시 할 것입니다. –

관련 문제