문제

메모리 누출 문제를 디버깅하려고합니다. 사용 중입니다 mtrace () malloc/free/realloc 추적을 얻으려면. 나는 내 프로그램을 실행했고 이제 거대한 로그 파일을 가지고 있습니다. 여태까지는 그런대로 잘됐다. 그러나 파일을 해석하는 데 문제가 있습니다. 이 라인을보십시오.

@ /usr/java/ibm-java2-x86_64-50/jre/bin/libj9prt23.so:[0x2b270a384a34] + 0x1502570 0x68
@ /usr/java/ibm-java2-x86_64-50/jre/bin/libj9prt23.so:[0x2b270a384a34] + 0x1502620 0x30
@ /usr/java/ibm-java2-x86_64-50/jre/bin/libj9prt23.so:[0x2b270a384a34] + 0x2aaab43a1700 0xa80
@ /usr/java/ibm-java2-x86_64-50/jre/bin/libj9prt23.so:[0x2b270a384a34] + 0x1501460 0xa64

이것에 대한 이상한 점은 하나의 전화 (동일한 반품 주소)가 4 개의 할당에 책임이 있다는 것입니다.

심지어 낯선 사람 :

@ /usr/java/ibm-java2-x86_64-50/jre/bin/libj9prt23.so:[0x2b270a384a34] + 0x2aaab43a1700 0xa2c
…
@ /usr/java/ibm-java2-x86_64-50/jre/bin/libj9prt23.so:[0x2b270a384a34] + 0x2aaab43a1700 0xa80

이 두 줄 사이에 블록 0x2AAAB43A1700은 절대로 해제되지 않습니다.

이것을 설명하는 방법을 아는 사람이 있습니까? 한 번의 호출은 어떻게 4 개의 할당으로 인해 발생할 수 있습니까? 그리고 Malloc은 어떻게 이전에 이미 할당 된 주소를 반환 할 수 있습니까?

편집 2008/09/30 : GLIBC (mtrace.pl)가 제공 한 mtrace () 출력을 분석하는 스크립트는 여기서 도움이되지 않습니다. Alloc 0x2aaab43a1700 복제. 그러나 어떻게 이런 일이 일어날 수 있습니까?

도움이 되었습니까?

해결책

메모리를 할당하는 함수는 두 번 이상 호출됩니다. 발신자 주소는 할당을 수행 한 코드를 가리키며 해당 코드는 단순히 두 번 이상 실행됩니다.

다음은 C의 예입니다.

void *allocate (void)
{
  return (malloc(1000));
}

int main()
{
  mtrace();
  allocate();
  allocate();
}

mtrace의 출력은 다음과 같습니다.

Memory not freed:
-----------------
           Address     Size     Caller
0x0000000000601460    0x3e8  at 0x4004f6
0x0000000000601850    0x3e8  at 0x4004f6

발신자 주소가 어떻게 동일합니까? 그렇기 때문에 스크립트를 분석하는 스크립트가 동일하다고 말하는 이유는 동일한 버그가 한 번 더 많이 보이기 때문에 여러 메모리 누출이 발생하기 때문입니다.

디버그 플래그 (-G)로 컴파일하는 경우 도움이됩니다.

Memory not freed:
-----------------
           Address     Size     Caller
0x0000000000601460    0x3e8  at /home/andrjohn/development/playground/test.c:6
0x0000000000601850    0x3e8  at /home/andrjohn/development/playground/test.c:6

다른 팁

당신은 매우 혼란스럽고 반 직관적 인 mtrace의 직접 출력을보고 있습니다. 운 좋게도, Perl 스크립트 (glibc-utils 내에서 발견되는 mtrace라고 함)가 있어이 출력의 구문 분석에 매우 쉽게 도움이 될 수 있습니다.

디버깅 켜기로 빌드를 컴파일하고 MTRACE와 같이 실행하십시오.

$ gcc -g -o test test.c
$ MALLOC_TRACE=mtrace.out ./test
$ mtrace test mtrace.out

Memory not freed:
-----------------
   Address     Size     Caller
0x094d9378    0x400  at test.c:6

출력은 a입니다 많은 소화하기가 더 쉽습니다.

한 가지 가능한 설명은 동일한 함수가 다른 버퍼 크기를 할당하고 있다는 것입니다. 그러한 예 중 하나는 strdup입니다.

두 번째 질문의 경우, 런타임이 프로세스가 종료 될 때까지 해제되지 않는 일부 "정적"스크래치 영역을 할당 할 수 있습니다. 그리고 그 시점에서 OS는 어쨌든 프로세스 후에 정리됩니다.

이런 식으로 생각하십시오 : Java에는 소멸자가 없으며, 결승전이 어떤 물건에도 요구 될 것이라는 보장은 없습니다.

Valgrind에서 앱을 실행해보십시오. 실제로 유출되는 것에 대한 더 나은 견해를 줄 수 있습니다.

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