2011-09-22 3 views
5

내 간단한 C 프로그램 (gnu linux)에서 proc/stat에서 rss 값을 얻고 있습니다.
int GetRSS()은 내 프로세스에 대한 proc/stat에서 RSS 값을 반환합니다. 이 경우 광기는 무료입니다.


:

printf("A RSS=%i\n", GetRSS()); 
char *cStr = null; 
cStr = malloc(999999); 
if (cStr != NULL) 
{ 
    printf("B RSS=%i\n", GetRSS()); 
    free(cStr); 
    printf("C RSS=%i\n", GetRSS()); 
} 

내가 얻을 :

A RSS=980 
B RSS=984 
C RSS=980 

C984를 반환하지 않은 이유를 설명 할 수 없다. 내가 두 번 같은 절차를 실행하면


내가 얻을 :

A RSS=980 
B RSS=984 
C RSS=980 
B RSS=984 
C RSS=980 

잘 보인다. 이 경우에


하지만, :

struct _test 
{ 
    char *pChar; 
} 
struct _test **test_ptr; 

int i = 0; 
printf("D RSS=%i\n",GetRSS()); 
assert(test_ptr = (struct _test **)malloc((10000) * sizeof(struct _test *))); 

for (i = 0; i < 1000; i++) 
{ 
    assert(test_ptr[i] = (struct _test *)malloc(sizeof(struct _test))); 
    test_ptr[i]->pChar=strdup("Some garbage"); 
} 

printf("E RSS=%i\n", GetRSS()); 

for (i=0; i<1000; i++) 
{ 
    free(test_ptr[i]->pChar); 
    free(test_ptr[i]); 
} 

free(test_ptr); 
printf("F RSS=%i\n", GetRSS()); 

내가 얻을 :

D RSS=980 
E RSS=1024 
F RSS=1024 
D RSS=1024 
E RSS=1024 
F RSS=1024 

응? 기억이 왜 여기에서 자유롭지 않습니까?

+9

부작용이있는 표현식을 절대로 '단정'해서는 안됩니다. –

+0

사실 충분합니다. 무시해. 여전히 결과는 당황 스럽습니다. –

+1

"strace"아래에서 프로그램을 실행하면 실제로 RSS 값에 영향을 미치는 mmap/munmap 호출을 모니터링 할 수 있습니다.mmap/munmap을 출력에서 ​​코드의 특정 지점과 일치시킬 수 있도록 코드 주위에 printfs를 넣을 수 있습니다. – vanza

답변

5

메모리 블록이 해제되었다는 사실은 이 아니기 때문에은 반드시 해당 블록을 후속 할당에 가장 적합하게 만듭니다. 메모리 관리자가 메모리 블록을 선택하기위한 몇 가지 전략이 있습니다 (최적, 최악, 첫 번째).

대부분의 메모리 관리자는 또한 자유 블록을 합치려고 시도하지만, 일부는 자유 블록을 "오래"가능한 한 오랫동안 합치기 전에 시도합니다. 이론적으로, 그들은 나이가 들수록 옆에있는 블록이 또한 해제되어 블록 결합시 성공률이 향상되므로 조각화가 줄어 듭니다.

블록이 다음 할당 요청을 만족시키는 데 사용되지 않았다는 사실은 이 아니며은 해제되지 않았 음을 의미합니다.

1

귀하의 malloc 라이브러리가 이것을 선택하지 않았습니다. 전략적 이유로 (추후 더 많은 메모리를 얻기 위해 시스템에 가야하는 것을 피하기 위해) 또는 제한으로 인한 것일 수 있습니다 (특정 원인에서 메모리를 확보 할 수 있음을 인식하지 못함).

일반적으로 중요하지 않습니다. 주소 공간과 가상 메모리는 일반적으로 희소 자원으로 간주되지 않습니다. 따라서 소비를 최소화하기위한 과도한 노력은 일반적으로 무의미하며 때로는 해롭다.

2

free() 맨 페이지에서 : "종종 free는 실제로 운영 체제에 메모리를 반환하여 프로세스를 더 작게 만들 수 있습니다. 일반적으로 나중에 malloc을 호출하여 공간을 다시 사용할 수 있습니다. 공간은 프로그램에서 malloc에 ​​의해 내부적으로 사용되는 프리리스트의 일부로 남아 있습니다. "

+0

이 질문을 만든 실제 프로그램의 경우 결국 메모리가 부족해져 충돌이 발생합니다. 내 테스트는 구조체에 할당 된 메모리가 공개되지 않음을 보여줍니다. 또한 strace는 malloc과 연관된 mmap2 또는 munmap 호출을 표시하지 않고 구조체 (및 해당 char *)가 없음을 표시합니다. 나는 아직도 곤란하다. –

+0

@ MarkRichards : 방금 WinDbg에서 프로그램을 밟았습니다. (리눅스 시스템을 가지고 놀지 않아도됩니다.) 커밋 된 메모리를'! heap'으로 검사했습니다. 그것은 잘 작동합니다. 메모리 누수가없는 것 같습니다. glibc의'malloc'과'free'는 이미 mmap/munmap을 호출 할 필요가 없다는 것을 기억하십시오. 왜냐하면 이미 CRT 힙을 위해 예약 된 메모리가 없기 때문입니다. 궁극적으로 추억과 추락을 의미하는 것은 무엇입니까? 어쩌면 전체 프로그램을 붙여 넣을 수 있습니까? –

+0

매우 흥미 롭습니다. 다른 (다른) 상자에서도 똑같이 할 것입니다. 나는 프로그램을 수정했다. malloc을 작동시킨 첫 번째 프로그램을 삭제했다. 그래도 mmap을 호출하지 못합니다. 참조하십시오 : http://pastebin.com/m3gAJBhs –

관련 문제