문제

나는 다음과 같은 코드:

MemoryStream foo(){
    MemoryStream ms = new MemoryStream();
    // write stuff to ms
    return ms;
}

void bar(){
    MemoryStream ms2 = foo();
    // do stuff with ms2
    return;
}

어떤 기회가있는 MemoryStream 는 할당을 어떻게든 실패를 폐기하나요?

나는 투고 주장하는 것이 나을 수동으로 가까이,그리고 나는 정보를 찾아낼 수 없다면 말하는 그는 올바른점을 지지 않습니다.

도움이 되었습니까?

해결책

무언가가 일회용이라면 항상 처분해야합니다. Bar () 메소드에서 사용 명령문을 사용하여 MS2가 폐기되도록해야합니다.

그것은 결국 쓰레기 수집가에 의해 청소 될 것이지만, 항상 처분하는 것은 항상 좋은 관행입니다. 코드에서 fxcop을 실행하면 경고로 표시됩니다.

다른 팁

적어도 현재 구현에서는 아무것도 새지 않을 것입니다.

Dispose 호출은 MemoryStream에서 사용하는 메모리를 더 빨리 정리하지 않습니다. 그것 ~ 할 것이다 통화 후 읽기/쓰기 통화에 대한 스트림이 실행 가능하지 않도록하십시오.

당신이 절대적으로 당신을 확신한다면 절대 메모리 스트림에서 다른 종류의 스트림으로 이동하고 싶을 때, 그것은 당신에게 dispose를 부르지 않기 위해 해를 끼치 지 않을 것입니다. 그러나, 그것은 당신이 그 어느 때에도 하다 다른 스트림을 사용하기 위해 변경하면 쉽게 벗어나기 어려운 버그에 물린 것을 일찍 선택하기 때문에 변경하고 싶지 않습니다. (반면에 Yagni 주장이 있습니다 ...)

어쨌든 그렇게해야 할 또 다른 이유는 새로운 구현이기 때문입니다. 5월 처분 할 때 해방 될 자원을 소개합니다.

그렇다 a 누출,을 정의하는 방법에 따라 누액이 얼마나 나중에는 것을 의미...

다면 누출을 의미하는"계속 메모리를 할당할 수 없을 사용하더라도,당신은 그것을 사용하여 할"와 후미 후 언제든지 전화 처분,그때 그 예가 될 수 있습 누출지만,그 영원하지 않다(i.e의 삶에 대한 귀하의 응용 프로그램 런타임).

을 무료로 관리 open icecat 콘텐츠 배포업체를 통해 사용됩 MemoryStream, 당신이 필요하 unreference 그, 로,무효 당신이 그것을 참조하므로 그것을 가비지 컬렉션의 대상이 됩니다.당신이 실패하는 경우 이를 위해,당신은 만들기 임시에서 누출 시간은 당신을 사용하여 수행 될 때까지,그것을 참조 범위를 벗어나기 때문에,그 동안에는 메모리를 사용할 수 없을 위한 할당입니다.

의 이익을 사용하여 계산서(단순히 부르 폐기)는 선언할 수 있습니다 참조에 사용하는 문입니다.할 때 사용하여 문이 완료 뿐만 아니라 처분이라는,그러나 당신의 참고의 범위,효과적으로 무효로 하는 기준을 만드는 객체를 가비지 컬렉션 대상으로 즉시 필요없이 당신을 기억을 쓰는"참조=null"코드입니다.

는 동안 실패 unreference 바로 뭔가가 아닌 클래식"영구적"메모리 누수,그것은 확실히 동일한 효과를 얻습니다.예를 들어,당신의 참고를 MemoryStream(도 호출 한 후 폐기),그리고 조금 더에 당신의 방법을 시도해 더 많은 메모리를 할당...에서 메모리를 사용하여 아직도 참조 메모리 스트림을 사용할 수 없을 때까지 당신이 무효화 참조 또는 그것의 범위는,비록 당신이라고 폐기 및를 사용하여 수행됩니다.

이것은 이미 답변되었지만, 좋은 구식 정보 숨기기 원칙은 미래에 어떤 시점에서 리팩터를 리팩터링하고 싶어 할 수 있다고 덧붙였다.

MemoryStream foo()
{    
    MemoryStream ms = new MemoryStream();    
    // write stuff to ms    
    return ms;
}

에게:

Stream foo()
{    
   ...
}

이는 발신자가 어떤 종류의 스트림이 반환되는지 신경 쓰지 않아야하며, 내부 구현 (예 : 단위 테스트를위한 조롱시)을 변경할 수있게한다는 것을 강조합니다.

그런 다음 바 구현에 처분을 사용하지 않으면 문제가 필요합니다.

void bar()
{    
    using (Stream s = foo())
    {
        // do stuff with s
        return;
    }
}

모든 스트림은 idisposable을 구현합니다. 사용 명령문으로 메모리 스트림을 감싸면 괜찮고 멍청해질 것입니다. 사용 블록은 스트림이 무엇이든 닫히고 배치되도록합니다.

FOO라고 부르는 곳마다 (MemoryStream MS = foo ())를 사용할 수 있으며 여전히 괜찮을 것 같습니다.

부름 .Dispose() (또는 포장 Using) 필요하지 않습니다.

당신이 전화하는 이유 .Dispose() 그렇습니다 가능한 빨리 리소스를 해제하십시오.

예를 들어, 스택 오버 플로우 서버 (Stack Overflow Server)는 제한된 메모리 세트와 수천 건의 요청이 들어오는 것입니다. 우리는 예정된 쓰레기 수집을 기다리고 싶지 않으므로 해당 메모리를 최대한 빨리 해제하여 사용할 수 있습니다. 새로운 수신 요청.

지 메모리 누수,하지만 당신의 코드를 검토하여 정확을 나타내 닫아야 합니다.그것은 예의이다.

유일한 상황에서는 당신은 수 있는 메모리 누수가 발생할 때 당신은 실수로 남겨 참조 스트림에 결코 그것을 닫습니다.당신은 여전히지 않는 메모리 누수,하지만 당신 불필요하게 확장하는 시간을 주장하는 그것을 사용하고 있다.

메모리 스트림을 포장하는 것이 좋습니다 bar() 안에 using 주로 일관성을위한 진술 :

  • 지금 MemoryStream은 메모리를 자유롭게하지 않습니다 .Dispose(), 그러나 미래의 어느 시점에서 또는 귀하 (또는 회사의 다른 사람)가이를 자신의 사용자 지정 메모리 스트림으로 대체 할 수 있습니다.
  • 프로젝트에서 패턴을 설정하여 보장하는 데 도움이됩니다. 모두 스트림이 폐기됩니다. "일부 스트림은 폐기되어야하지만 특정 스트림은 폐기해야하지만 특정 스트림은"... "...
  • 다른 유형의 스트림을 반환 할 수 있도록 코드를 변경하면 어쨌든 폐기하도록 변경해야합니다.

내가 보통 같은 경우에하는 또 다른 일 foo() idisposable을 작성하고 반환 할 때 객체 구성과 return 예외에 의해 잡히고, 객체를 처리하고, 예외를 재검토합니다.

MemoryStream x = new MemoryStream();
try
{
    // ... other code goes here ...
    return x;
}
catch
{
    // "other code" failed, dispose the stream before throwing out the Exception
    x.Dispose();
    throw;
}

객체가 idisposable을 구현하는 경우 완료되면 .Dispose 메소드를 호출해야합니다.

일부 개체에서는 처분은 가까운 것과 동일하고 그 반대의 경우도 마찬가지입니다.이 경우 어느 쪽도 좋습니다.

이제 특정 질문에 대해서는 메모리가 새지 않을 것입니다.

저는 .NET 전문가가 아니지만 여기서 문제는 리소스, 즉 메모리가 아닌 파일 핸들 일 것입니다. 쓰레기 수집가가 결국 스트림을 풀고 손잡이를 닫을 것이라고 생각하지만, 내용물을 디스크로 플러시하는지 확인하기 위해 항상 명시 적으로 닫는 것이 가장 좋습니다.

관리되지 않는 자원의 처분은 쓰레기 수집 된 언어에서 비 결정적입니다. 명시 적으로 처분을 호출하더라도, 백킹 메모리가 실제로 해제 될 때를 통제 할 수 없습니다. Dispose는 객체를 사용하여 명령문을 종료하거나 종속 메소드에서 Callstack을 팝업하는지 여부에 관계없이 객체가 범위를 벗어나면 암시 적으로 호출됩니다. 이것은 모든 것이 말하면, 때로는 객체가 실제로 관리 자원 (예 : 파일)의 래퍼 일 수 있습니다. 그렇기 때문에 최종적으로 명시 적으로 명시 적으로 문을 닫거나 사용 명령문을 사용하는 것이 좋습니다. 건배

MemorySteram은 관리되는 개체 인 바이트 배열 일뿐입니다. 처분하거나 닫는 것을 잊어 버리십시오. 이것은 결승전의 책임 외에는 부작용이 없습니다.
반사기에서 MemoryStream의 Conftuctor 또는 Flush Method를 점검하면 모범 사례를 따르는 문제가 아닌 다른 사람을 폐쇄하거나 폐기 할 필요가없는 이유가 분명합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top