2012-06-11 3 views
4

저는 새로운 프로그래머이고 방금 메모리 누수 문제를 생각해냅니다. 루프에서 변수를 반복하여 선언하도록하면 메모리가 누출됩니까? 예를 들어, 나는 그것이 무한 루프 알고루프에서 메모리 누출이 있습니까?

while(true) 
{ 
    Image<Gray, Byte> MyImage = new Image<Gray, Byte> (1024, 768); 
    //do something else 
} 

을 가지고 있지만 내 질문에 메모리에 관한 것입니다. 이 루프에서 메모리 사용이 빠르게 증가하고 있습니까? MyImage를 수동으로 출시해야합니까?

+0

나는 추측 할 위험이 있으며 그렇다고 대답하지만, 100 % 확신 할 수는 없으므로 복음으로 받아들이지 마십시오. – Richard

+0

@Killercam 확실한가요? 나는 뭔가 다른 것을 듣기 때문에 나는 모른다. 이 경우 이미지 객체가 괜찮다는 의미입니까, 일반적으로 말합니까? – YankeeWhiskey

답변

6

사용 후 MyImage.Dispose()으로 전화해야합니다. 내가 다시하고 다시 선언 할 수 있도록 루프에서 변수를 선언하는 경우

while(true) 
{ 
    using(Image<Gray, Byte> MyImage = new Image<Gray, Byte> (1024, 768)){ 
     //do something else 
    } 
} 
+0

클래스가'IDisposable'을 구현하지 않을 수도 있다는 것을 깨달았습니다. 따라서 IDisposable을 구현하거나 IDisposable을 구현하는 무언가를 사용한다면 가져 오십시오.이 경우 내부 객체를 폐기하기 위해 구현해야합니다. – ivowiblo

+0

효율성을위한 것입니까 아니면 실제 메모리 누수입니까? – YankeeWhiskey

+0

IDisposable 클래스는 일반적으로 Dispose() 메서드가 호출 될 때까지 사용할 수없는 메모리를 사용합니다. 무한 루프에서 사용할 수 있으므로 메모리 누수가 발생할 수 있습니다. Dispose를 호출하지 않고 Disposable 객체를 사용하는 경우 메모리 누수가 발생합니다. – ivowiblo

1

내가 메모리가 누수 있습니까 :

또 다른 방법으로 코드를 변경하는 것입니다?

이미지 Image 객체

하지만 당신의 질문에 대한 포장되는 경우 아니, 당신은, 다른 사람에 의해 언급 한 바와 같이 문제가 될 수 없습니다, 그것은 루프 내부 변수를 선언 할 수있는 문제가 아니며, 각 반복마다 새 값을 할당하십시오.

1

엄격한 루프가 OOM 문제를 일으킬 수있는 상황이 있습니다. 그러나 ImageIDisposable을 구현하므로 using 문을 통해 호출해야 리소스를 완료 할 때 리소스를 확보 할 수 있습니다. Image<T,U>는 모든 관리 객체를 구현하는 경우

using (Image<Gray, Byte> MyImage = new Image<Gray, Byte>(1024, 768)) 
{ 
    //do stuff 
} 

IDisposable 확인 Image<T,U> 구현을합니다.

1

질문의 일반적인 형태로는 메모리 자체가 새는 것은 아니지만 GC가 사용량을 줄이는 것보다 빠르게 메모리 사용 공간을 늘릴 수 있습니다 (사용하는 개체의 정확한 동작 및 메모리 점유에 따라 달라질 수 있음).). 그렇다면 많은 메모리 누수와 같은 효과가 있습니다.

특정 예로 Image 개체에는 메모리 (또는 파일 핸들 또는 GDI 개체 등)가 포함될 수있는 관리되지 않는 리소스가 있습니다. 다른 답변에서 알 수 있듯이 처분하지 않으면 관리되지 않는 리소스가 회수되지 않습니다 (또는 GC의 두 번째 단계에서 최종 사용자가있는 경우 다시 회수 될 수 있음).

3

가비지 수집기 (GC)가 결국이 작업을 수행합니다. 여러분이 제안한 것과 같은 경우 GC는이 경우 GC가 가비지 수집과 응용 프로그램 메모리 소비 (작업 집합)를 비교하는 데 소요되는 시간을 관리하고 관리하므로주의해야합니다. 결과적으로 응용 프로그램은 사용자가 설명하는 경우 특히 필요로하는 것보다 많은 메모리를 소비 할 수 있습니다.

CLR은이 메모리를 완전히 자동으로 처리하므로 관리되는 메모리를 직접 할당 취소하지 마십시오. 예를 들어 다음을 고려

public void Test() 
{ 
    byte[] myArray = new Byte[1000]; 
    // ... 
} 

Test이 실행이 1000 바이트를 저장할 배열 메모리 힙에 할당 될 때. 배열은 변수 myArray에 의한 참조이며 로컬 변수 스택에 저장됩니다. 이 메서드가 종료되면이 로컬 변수가 범위를 벗어나 튀어 나와 메모리 힙의 배열을 참조하는 데 아무 것도 남지 않습니다. 분리 된 배열은 GC에 의해 재 확보 될 자격을 갖게됩니다.그러나 CLR이 수집할지 여부에 대한 결정은 여러 가지 요소 (사용 가능한 메모리, 현재 메모리 할당, 마지막 수집 이후 시간 등)를 기반으로하므로 즉시 수행되지 않을 수 있습니다. 즉, 쓰레기 수거 전의 시간.

위에서 설명한 것처럼 루프/포함 메서드의 지속 기간 동안 메모리 소비가 크게 증가합니다. 여기에는 using

while (true) 
{ 
    using (Image<Gray, Byte> MyImage = new Image<Gray, Byte> (1024, 768)) 
    { 
     // ... 
    } 
} 

또는 각 루프 후 Image 객체에 dispose()를 호출을 사용하거나 훨씬 낫다.

while (true) 
{ 
    Image<Gray, Byte> MyImage = new Image<Gray, Byte> (1024, 768); 
    // ... 
    MyImage.Dispose(); 
} 

Asside : 당신은 항상 자신을 위해 메모리 소비를 체크 아웃 (System.Diagnostics 네임을 사용하여) 성능 카운터를 쿼리하여 (귀하의 프로세스 실제 메모리 소비를 테스트) 할 수

string procName = Process.GetCurrentProcess().ProcessName; 
using (PerformanceCounter pc = new PerformanceCounter("Process", "Private Bytes", procName)) 
    Console.WriteLine(pc.NextValue()); 

주 읽기 성능 카운터에는 관리자 권한이 필요합니다.

관련 문제