DLL 언로드 시 메모리 누수로 인해 호스트 프로세스에 누수가 발생합니까?

StackOverflow https://stackoverflow.com/questions/132242

문제

이 경우를 고려하십시오.

dll = LoadDLL()
dll->do()

...
void do() {
    char *a = malloc(1024);
}
...

UnloadDLL(dll);

이 시점에서 malloc() 호출에 할당된 1k를 호스트 프로세스에서 다시 사용할 수 있습니까?DLL은 CRT에 정적으로 연결됩니다.

도움이 되었습니까?

해결책

아니요, 누출되지 않습니다.

DLL 모델 (정적, 동적)을 혼합하면 DLL에 메모리를 할당하면 메모리 오류로 끝날 수 있습니다.

이는 정적으로 연결된 CRT에 의해 생성 된 힙이 다른 DLL의 CRT와 동일하지 않음을 의미합니다.

CRT의 동적 버전과 연결되면 힙이 동적으로 연결된 모든 CRT 사이에서 공유되므로 누출이 발생합니다. 즉, 동적 CRT를 사용하기 위해 항상 앱을 설계하거나 DLL 경계를 통해 메모리를 관리하지 않도록해야합니다 (즉, DLL에 메모리를 할당하는 경우 항상 동일한 DLL에서 해방하는 루틴을 제공합니다).

다른 팁

  1. OS에서 추적하는 프로세스에서 사용하는 메모리는 DLL에만 국한되지 않고 전체 프로세스에 적용 가능합니다.

  2. 메모리는 OS에 의해 힙이라고 불리는 덩어리로 프로그램에 제공됩니다.

  3. 힙 관리자(malloc/new 등)는 청크를 추가로 나누어 요청 코드에 전달합니다.

  4. 새 힙이 할당된 경우에만 OS가 메모리 증가를 감지합니다.

  5. DLL이 CRT(C 런타임 라이브러리)에 정적으로 연결되면 DLL 코드가 호출하는 CRT 함수가 포함된 CRT의 전용 복사본이 컴파일되어 DLL의 바이너리에 저장됩니다.Malloc도 여기에 포함됩니다.

  6. 이 malloc의 개인 복사본은 정적으로 링크된 DLL 내부에 있는 코드가 메모리 할당을 시도할 때마다 호출됩니다.

  7. 결과적으로 이 malloc 복사본에만 표시되는 개인 힙은 이 malloc에 ​​의해 OS에서 획득되고 이 개인 힙 내의 코드에서 요청한 메모리를 할당합니다.

  8. DLL이 언로드되면 해당 개인 힙이 언로드되며, 전체 힙이 OS로 다시 반환되므로 이 누출은 눈에 띄지 않게 됩니다..

  9. 그러나 DLL이 동적으로 연결된 경우 메모리는 공유 모드에서 연결된 모든 코드에 전역적으로 적용되는 단일 공유 버전의 malloc에 ​​의해 할당됩니다.

  10. 이 전역 malloc에 ​​의해 할당된 메모리는 동적 일명 공유 모드로 연결되어 공통되는 다른 모든 코드에 사용되는 힙이기도 한 힙에서 나옵니다.따라서 이 힙에서 발생하는 누수는 전체 프로세스에 영향을 미치는 누수가 됩니다.

편집 - 연결 시나리오에 대한 설명을 추가했습니다.

당신은 말할 수 없습니다. 이것은 정적 및 동적 CRT의 구현에 따라 다릅니다. 그것은 심지어에 따라 다를 수 있습니다 크기 할당 중, OS에 큰 할당을 전달하는 CRT가 있지만 작은 할당을위한 자체 힙을 구현합니다.

누출이 발생하는 CRT의 문제는 물론 누출되는 것입니다. 누출되지 않는 CRT의 문제점은 실행 파일이 합리적으로 메모리를 사용할 것으로 예상 할 수 있다는 것입니다.

MSDN에서 DLL 경계에 걸쳐 CRT 객체를 전달하는 잠재적 오류

CRT 라이브러리의 각 사본에는 별도의 별도의 상태가 있습니다. 따라서 파일 핸들, 환경 변수 및 로케일과 같은 CRT 객체는 이러한 객체가 할당되거나 설정되는 CRT 사본에만 유효합니다. DLL과 사용자가 CRT 라이브러리의 다른 사본을 사용하면 DLL 경계를 가로 질러 이러한 CRT 객체를 전달할 수 없으며 다른 쪽에서 올바르게 선택할 것으로 기대합니다.

또한 CRT 라이브러리의 각 사본에는 자체 힙 관리자가 있기 때문에 하나의 CRT 라이브러리에 메모리를 할당하고 DLL 경계를 가로 질러 포인터를 전달하여 CRT 라이브러리의 다른 사본에 의해 해방 될 수 있습니다.

도움이 되었기를 바랍니다.

실제로, 표시된 대답이 잘못되었습니다. 바로 누출이 있습니다. 각 DLL이 자체 힙을 구현하고 셧다운시 무료로 사용하는 것은 기술적으로 실현 가능하지만 대부분의 "런타임"힙은 정적 또는 동적 - Win32 프로세스 힙 API 주위의 래퍼입니다.

그렇지 않다는 것을 보장하기 위해 구체적인주의를 기울이지 않는 한, DLL은 부하당 할당, DO, 언로드 사이클을 누출합니다.

테스트를 수행하고 메모리 누출이 있는지 확인할 수 있습니다. 매번 1MB를 할당하는 간단한 테스트를 30 회 실행합니다. 당신은 그것을 아주 빨리 알아 내야합니다.

한 가지는 확실합니다. DLL에 메모리를 할당 한 경우 (DLL에서) 해당 메모리를 제거해야합니다.

예를 들어 이와 같은 것이 있어야합니다 (간단하지만 직관적 인 의사 코드) :

dll = DllLoad();

ptr = dll->alloc();

dll->free(ptr);

DllUnload(dll);

DLL은 원래 프로세스 (DLL을로드하는)와 다른 힙을 갖기 때문에 수행해야합니다.

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