문제

나는 10 년 동안 C ++를 썼습니다. 메모리 문제가 발생했지만 합리적인 노력으로 고칠 수있었습니다.

지난 몇 년 동안 나는 C#을 쓰고 있습니다. 나는 여전히 많은 메모리 문제가 있습니다. 비 결정으로 인해 진단하고 고치기가 어렵습니다. C# 철학은 당신이 매우 확실히 할 때 그러한 것들에 대해 걱정할 필요가 없기 때문입니다.

내가 찾은 한 가지 특별한 문제는 코드의 모든 것을 명시 적으로 폐기하고 정리해야한다는 것입니다. 내가 그렇지 않다면, 메모리 프로파일 러는 당신에게 너무 많이 떠 다니기 때문에 그들이 당신에게 보여 주려고하는 모든 데이터에서 누출을 찾을 수 없기 때문에 실제로 도움이되지 않습니다. 내가 잘못된 아이디어를 얻었는지 또는 내가 가진 도구가 최고가 아닌지 궁금합니다.

.NET에서 메모리 누출을 다루는 데 어떤 종류의 전략과 도구가 유용합니까?

도움이 되었습니까?

해결책

나는 scitech를 사용합니다 memprofiler 메모리 누출이 의심 될 때.

지금까지 나는 그것이 매우 신뢰할 수 있고 강력하다는 것을 알았습니다. 그것은 적어도 한 번은 내 베이컨을 구했습니다.

GC는 .NET IMO에서 매우 잘 작동하지만 다른 언어 나 플랫폼과 마찬가지로 나쁜 코드를 작성하면 나쁜 일이 발생합니다.

다른 팁

잊어 버리는 문제만으로 시도해보십시오 이 블로그 게시물에 설명 된 솔루션. 본질은 다음과 같습니다.

    public void Dispose ()
    {
        // Dispose logic here ...

        // It's a bad error if someone forgets to call Dispose,
        // so in Debug builds, we put a finalizer in to detect
        // the error. If Dispose is called, we suppress the
        // finalizer.
#if DEBUG
        GC.SuppressFinalize(this);
#endif
    }

#if DEBUG
    ~TimedLock()
    {
        // If this finalizer runs, someone somewhere failed to
        // call Dispose, which means we've failed to leave
        // a monitor!
        System.Diagnostics.Debug.Fail("Undisposed lock");
    }
#endif

우리는 사용했습니다 개미 프로파일 러 프로 우리 프로젝트의 Red Gate 소프트웨어에 의해. 모든 .NET 언어 기반 애플리케이션에 실제로 잘 작동합니다.

우리는 .NET 쓰레기 수집기가 메모리 내 물체를 청소할 때 매우 "안전하다"는 것을 발견했습니다. 그것은 우리가 우리 때문에 물체를 유지할 것입니다 ~할 것 같다 미래에 언젠가 그것을 사용하고 있습니다. 이것은 우리가 기억에 팽창 한 물체의 수에 대해 더 조심해야한다는 것을 의미했습니다. 결국, 우리는 메모리 오버 헤드를 줄이고 성능을 향상시키기 위해 모든 데이터 객체를 "주문형 팽창"(필드를 요청하기 직전)으로 변환했습니다.

편집 : 다음은 "요구에 부풀어 오른다"는 의미에 대한 추가 설명이 있습니다. 데이터베이스의 객체 모델에서 부모 객체의 속성을 사용하여 Child Object를 노출시킵니다. 예를 들어, 일대일로 다른 "세부 사항"또는 "조회"레코드를 참조하는 레코드가 있다면 다음과 같이 구성 할 것입니다.

class ParentObject
   Private mRelatedObject as New CRelatedObject
   public Readonly property RelatedObject() as CRelatedObject
      get
         mRelatedObject.getWithID(RelatedObjectID)
         return mRelatedObject
      end get
   end property
End class

우리는 위의 시스템이 메모리에 많은 레코드가있을 때 실제 메모리와 성능 문제를 일으킨다는 것을 발견했습니다. 그래서 우리는 객체가 요청 될 때만 팽창 된 시스템으로 전환했으며 필요할 때만 데이터베이스 호출이 완료되었습니다.

class ParentObject
   Private mRelatedObject as CRelatedObject
   Public ReadOnly Property RelatedObject() as CRelatedObject
      Get
         If mRelatedObject is Nothing
            mRelatedObject = New CRelatedObject
         End If
         If mRelatedObject.isEmptyObject
            mRelatedObject.getWithID(RelatedObjectID)
         End If
         return mRelatedObject
      end get
   end Property
end class

물체가 필요할 때까지 기억을 벗어 났기 때문에 (Get 메소드에 액세스 되었음) 이것은 훨씬 더 효율적으로 판명되었습니다. 데이터베이스 히트를 제한하는 데있어 매우 큰 성능 향상과 메모리 공간에서 큰 이익을 제공했습니다.

응용 프로그램이 사소하지 않으면 관리 코드를 작성할 때 메모리에 대해 걱정해야합니다. 나는 두 가지를 제안하겠습니다 : 먼저 읽으십시오 C#을 통해 CLR .NET의 메모리 관리를 이해하는 데 도움이되기 때문입니다. 둘째, 도구와 같은 도구를 사용하는 법을 배우십시오 clrprofiler (Microsoft). 이것은 당신에게 메모리 누출을 일으키는 원인에 대한 아이디어를 줄 수 있습니다 (예 : 큰 물체 힙 조각화를 볼 수 있습니다).

관리되지 않는 코드를 사용하고 있습니까? Microsoft에 따르면 관리되지 않는 코드를 사용하지 않는 경우 전통적인 의미의 메모리 누출은 불가능합니다.

그러나 응용 프로그램에서 사용하는 메모리는 해제되지 않을 수 있으므로 애플리케이션의 메모리 할당이 응용 프로그램 수명 내내 커질 수 있습니다.

에서 Microsoft.com에서 공통 언어 런타임에서 메모리 누출을 식별하는 방법

응용 프로그램의 일부로 관리되지 않는 코드를 사용하면 .NET Framework 응용 프로그램에서 메모리 누출이 발생할 수 있습니다. 이 관리되지 않은 코드는 메모리를 유출 할 수 있으며 .NET Framework 런타임은 해당 문제를 해결할 수 없습니다.

또한 프로젝트는 메모리 누출 만있는 것처럼 보일 수 있습니다. 이 조건은 많은 큰 객체 (예 : 데이터 가능한 객체)가 선언 된 다음 컬렉션 (예 : 데이터 세트)에 추가 될 수 있습니다. 이러한 물체가 소유 한 리소스는 결코 공개되지 않을 수 있으며, 자원은 프로그램의 전체 실행을 위해 살아 남았습니다. 이것은 누출 인 것처럼 보이지만 실제로는 프로그램에 메모리가 할당되는 방식의 증상 일뿐입니다.

이러한 유형의 문제를 처리하려면 구현할 수 있습니다. idisposable. 메모리 관리를 다루기위한 몇 가지 전략을보고 싶다면 검색하는 것이 좋습니다. idisposable, XNA, 메모리 관리 게임 개발자는보다 예측 가능한 쓰레기 수집을 가져야하므로 GC가 그 일을하도록 강요해야합니다.

일반적인 실수 중 하나는 객체를 구독하는 이벤트 처리기를 제거하지 않는 것입니다. 이벤트 핸들러 구독은 객체가 재활용되는 것을 방지합니다. 또한, 사용 자원의 수명에 대한 제한된 범위를 만들 수있는 진술.

이 블로그 WINDBG 및 기타 도구를 사용하여 모든 유형의 메모리 누출을 추적하기 위해 정말 멋진 연습이 있습니다. 당신의 기술을 개발하기위한 훌륭한 독서.

방금 Windows 서비스에서 메모리 누출이 있었는데 수정했습니다.

먼저, 나는 시도했다 memprofiler. 나는 사용하기가 정말 어렵고 전혀 사용자 친화적이지 않다는 것을 알았습니다.

그런 다음 사용했습니다 JustTrace 사용하기 쉽고 올바르게 배치되지 않은 객체에 대한 자세한 내용을 제공합니다.

메모리 누출을 쉽게 해결할 수있었습니다.

관찰중인 누출이 런 어웨이 캐시 구현으로 인한 경우, 이것은 당신의 시나리오입니다. ~할 것 같다 약점의 사용을 고려하고 싶습니다. 이것은 필요할 때 메모리가 해제되도록하는 데 도움이 될 수 있습니다.

그러나 IMHO 맞춤형 솔루션을 고려하는 것이 좋습니다. 오직 물체를 주변에 유지하는 데 얼마나 오래 걸리는지 알고 있으므로 상황에 대한 적절한 하우스 키핑 코드를 설계하는 것이 일반적으로 최선의 방법입니다.

큰 총 - Windows 용 도구 디버깅 도구

이것은 놀라운 도구 모음입니다. 관리되지 않은 힙을 모두 분석 할 수 있으며 오프라인으로 수행 할 수 있습니다. 이것은 메모리 과용으로 인해 재활용을 유지 한 ASP.NET 응용 프로그램 중 하나를 디버깅하는 데 매우 편리했습니다. 프로덕션 서버에서 실행되는 생활 프로세스의 전체 메모리 덤프 만 만들어야했는데 모든 분석은 WINDBG에서 오프라인으로 수행되었습니다. (일부 개발자는 메모리 내 세션 스토리지를 과도하게 사용하고있는 것으로 밝혀졌습니다.)

"부러지면 ..." 블로그에는 주제에 대해 매우 유용한 기사가 있습니다.

명심해야 할 가장 좋은 점은 객체에 대한 참조를 추적하는 것입니다. 더 이상 신경 쓰지 않는 물체에 대한 언급으로 끝나는 것은 매우 쉽습니다. 더 이상 무언가를 사용하지 않으려면 제거하십시오.

슬라이딩 만료가있는 캐시 제공 업체를 사용하는 데 익숙해지면 원하는 시간 창을 위해 무언가를 참조하지 않으면 부정확하고 정리됩니다. 그러나 그것이 많이 액세스되면 기억으로 말할 것입니다.

가장 좋은 도구 중 하나는 사용하는 것입니다 Windows 용 도구 디버깅 도구, 그리고 사용 프로세스의 메모리 덤프 덤프 Adplus, 그런 다음 사용하십시오 Windbg 그리고 위급 신호 프로세스 메모리, 스레드 및 호출 스택을 분석하기 위해 플러그인을 사용하십시오.

이 방법을 사용하여 서버에서 문제를 식별하고 도구를 설치 한 후 디렉토리를 공유 한 다음 (NET 사용)를 사용하여 서버에서 공유에 연결 한 다음 프로세스의 충돌 또는 덤프를 취할 수 있습니다.

그런 다음 오프라인을 분석하십시오.

관리 응용 프로그램에 대한 내 수정 사항 중 하나 후에 다음 변경 후 응용 프로그램이 동일한 메모리 누출이 없는지 확인하는 방법과 같은 것과 같은 것이 었습니다. 객체 릴리스 확인 프레임 워크와 같은 것을 썼습니다. Nuget 패키지 objectReleaseverification. 여기에서 샘플을 찾을 수 있습니다 https://github.com/outcoldman/outcoldsolutions-objectreleaseverification-sample, 이 샘플에 대한 정보 http://outcoldman.ru/en/blog/show/322

나는 선호한다 도트 메모리 JetBrains에서

Visual Studio 2015에서 상자 밖으로 사용하는 것을 고려하십시오. 메모리 사용 진단 도구 메모리 사용 데이터를 수집하고 분석합니다.

메모리 사용 도구를 사용하면 관리 및 기본 메모리 힙의 하나 이상의 스냅 샷을 가져와 객체 유형의 메모리 사용 영향을 이해하는 데 도움이됩니다.

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