2009-10-01 1 views
7

C# 코드에서 관리되지 않는 C++ 코드를 호출하면 메모리 누수가 발생하는 것 같습니다.
C++은 ifstream.read를 사용하여 파일의 데이터를 읽고 Vector에 씁니다.Windows 7에서 관리 코드에서 비 관리 코드를 호출 할 때 메모리 누수가 발생했습니다.

이것은 Windows 7로 업그레이드 한 후에 발생하며 Vista에서는 발생하지 않지만 Vista에서 컴파일 된 원시 DLL 버전을 사용하면 아무 것도 변경되지 않습니다!
동일한 간섭 코드가없는 동일한 C++ 코드를 직접 실행하면 메모리 누수가 없습니다!
관리되는 프로세스를 실행하지만 vshost 프로세스 내에서 메모리 누수가 발생하지 않습니다!

 [DllImport(DllPath, CharSet = CharSet.Unicode)] 
    [return: MarshalAs(UnmanagedType.I1)] 
    public static extern bool MyMethod(
     int x, 
     string y, 
     string z, 
     bool v, 
     bool w); 

하고 원시 하나 : 나는 C++에서 호출

MyDll_Export bool APIENTRY MyMethod(
int x, 
const wchar_t* y, 
const wchar_t* z, 
bool v, 
bool w) 

, 나는 다음과 같이 호출 :

MyMethod(1, L"My String 1", L"My String 2", true, true) 

I를 여기

통화 서명입니다 관리되는 메모리와 관리되지 않는 메모리에 대한 성능 카운터를 살펴보면 모든 메모리가 비보안 코드에서 비롯된 것으로 나타났습니다.
마샬링이 매우 간단하다는 점을 감안할 때 C++을 직접 호출하거나 C#을 통해 호출하는 것의 차이점은 무엇인지 이해할 수 없습니다.
또한 왜 이것이 Windows 7에서만 발생하는지 (두 Windows 설치 모두 .net 3.5 SP1을 가졌음) 알지 못합니다.

누구에게 어떤 이유가 있을까요?

또한 Window 7에서 작동하는 네이티브 메모리 프로파일 링 도구를 아는 사람이라면 기꺼이 알 수 있습니다 (지금은 모든 명시 적 메모리 할당을 콘솔에 인쇄 했으므로 아무런 차이가 없습니다).

+0

LeakDiag [http://mcfunley.com/277/using-leakdiag-to-debug-unmanaged-memory-leaks] 또는 AutomatedQA의 AQTime은 관리되지 않는 누출 분석을 수행 할 수 있습니다. –

+0

메모리 소비 측정을 위해 어떤 성능 카운터를 사용합니까? –

+0

"vshost.exe"라는 질문에 태그를 지정했습니다. 메모리 사용량을 측정 할 때 응용 프로그램이 Visual Studio에서 실행됩니까? –

답변

5

문제는 C# 데이터 형식을 C++ 카운터 파트로 마샬링하는 것과 관련되어 있습니다. 반환 값 bool을 부호있는 1 바이트 값으로 마샬링하고 있기 때문에 함수 인수와 동일하게 처리해야할까요? C# bool 형식은 4 바이트입니다. 아마도 거기에 누수가 있습니까?

또한 문자열에 관리되지 않는 유형을 지정하면 도움이 될 수 있습니다.

[DllImport(DllPath, CharSet = CharSet.Unicode)] 
[return: MarshalAs(UnmanagedType.I1)] 
public static extern bool MyMethod(
     int x, 
     [MarshalAs(UnmanagedType.LPWStr)] 
     [In] string y, 
     [MarshalAs(UnmanagedType.LPWStr)] 
     [In] string z, 
     [MarshalAs(UnmanagedType.I1)] 
     bool v, 
     [MarshalAs(UnmanagedType.I1)] 
     bool w); 

commentor에 대한 설명 : 일반적으로

For the C++ bool type:

, 제로 또는 널 포인터 값이 false로 변환되고, 다른 값은 true로 변환됩니다.

...


1998 C++ 표준 라이브러리는 정의 부울의 벡터 템플릿의 특수화. 클래스의 설명에 따르면 구현시 요소를 모두 포함해야하므로 모든 bool은 메모리 1 비트에만 을 사용합니다.

따라서 사용하는 값이 무엇이든 관계없이 true 또는 false 값을 갖는 C++ 부울을 얻게됩니다.

+0

bool의 크기가 일치하지 않으면 메모리 누수가 아니지만 액세스 위반이 더 많을 수 있습니다. , 또는 어떤 종류의 스택 손상. – user7116

+0

멋진 파일 인 scott, C#은 bool을 4 바이트로 정렬합니다. v 및 w에 대해 marshalas 속성이 누락되었습니다. http://blogs.msdn.com/oldnewthing/archive/2009/08/13/9867383.aspx –

+0

err. '찾는다'라는 뜻의 –

2

불행히도 문자열을 포함하면 마샬링이 간단하지 않습니다.

이 문제를 추적하는 데 도움이되는 데이터가 더 필요합니다. 당신은

  • 이 어떻게 문자열에 대한 메모리가 네이티브 코드에서 관리되는 다음

    • 기본 방법 서명을 제공 할 수 있습니까?
    • 아마도 API를 사용하는 C++ 샘플일까요?

    편집은 다음과 같은 서명을보십시오. 이 두 방향으로 메모리를 마샬링 대신에서만 데이터를 전달하지 CLR을 알려줍니다.

    [DllImport(DllPath, CharSet = CharSet.Unicode)] 
        [return: MarshalAs(UnmanagedType.I1)] 
        public static extern bool MyMethod(
          int x, 
          [In] string y, 
          [In] string z, 
          bool v, 
          bool w); 
    
  • +0

    감사합니다. 업데이트 된 질문입니다. 전달 된 문자열은 상수입니다. –

    +0

    [In]이 도움이되지 않았다면 왜 Vista와 Windows 7이 바뀌었을까요? 또한이 메서드를 한 번만 호출한다고 언급하지 않았습니다. –

    1

    내 메모리 누수를 찾을 때 나는 CLR Profiler 도움의 사용을 발견했다.

    0

    메모리 누수가 발생 했습니까?

    메모리 누출을 판단 할 근거는 무엇입니까? 성능 카운터에서 볼 수 있다고하지만 실제로 무엇을 관찰하고 있습니까?당신은 연속적으로 상승하는 곡선을 보입니까, 아니면 높은 수준으로 떨어지는 곡선을 보십니까? 높은 메모리 소비는 종종 메모리 누수에 혼동을줍니다.

    btw. C++ 함수 정의도 게시 할 수 있습니까?

    +0

    계속 커브가 보입니다. 본문을 의미하는 C++ 함수 정의를 게시 한 다음 ifstream.read를 사용하여 파일에서 데이터를 읽습니다. –

    관련 문제