Egloos | Log-in
F/OSS study
F/OSS study
[glibc] 동적 메모리 관리 (3)
glibc: 2.10.1
arch: x86

이전 글 보기:

이번에는 malloc 모듈 내의 다른 보조 함수들에 대해서 알아보기로 한다.

가장 먼저 살펴볼 함수는 mallopt() 함수이다.
이 함수는 malloc() 시의 동작을 제어하는 다음과 같은 매개 변수들을 조정할 수 있다.
  • M_MXFAST: fast bin의 최대 크기이다. 기본값은 64로 설정되어 있으며 최대 80까지 늘릴 수 있다. (이 크기는 malloc() 시 주어지는 인자에 대한 것이며, 실제 chunk 크기는 이보다 약간 커진다.)
  • M_TRIM_THRESHOLD: free() 호출 시 병합된 chunk의 크기가 이 값보다 커지면 자동으로 sYSTRIm() 함수를 호출한다. 기본값은 128K이다.
  • M_TOP_PAD: top chunk가 기본적으로 유지하는 여유 공간의 크기이다. sYSMALLOc()을 통해 top chunk의 크기를 늘릴 때나 free() 시 sYSTRIm()이 top chunk의 크기를 줄일 때 사용하며, 기본값은 (문서와는 달리) 128K이다.
  • M_MMAP_THRESHOLD: sYSMALLOc()을 통해 시스템에 메모리 할당을 요청할 때 원하는 chunk의 크기가 이 값보다 크다면 sbrk() 대신 mmap()을 이용하여 할당한다. 기본값은 128K이다.
  • M_MMAP_MAX: mmap()을 이용하여 할당할 수 있는 chunk의 최대 개수이다. 기본값은 64K이다.
  • M_CHECK_ACTION: 메모리 할당 오류 시 취할 행동을 결정한다. 이 값이 5이면 간단한 메시지 만을 출력하고 NULL을 반환한다. 그렇지 않고 최하위 (0번) 비트가 설정되어 있으면 자세한 메시지를 출력하고 NULL을 반환한다. 그렇지 않고 1번 비트가 설정되어 있으면 abort()를 호출하여 프로세스를 바로 종료한다. 아무 비트도 설정되지 않았으면 단순히 NULL을 반환한다. 기본값은 3이다.
  • M_PERTURB: 메모리 테스트를 위한 패턴을 지정한다. 이 값이 0이 아니면 새로 할당된 메모리 영역을 모두 이 값을 이용하여 채운다. 기본값은 0이다.

사실 이러한 매개 변수들은 mallopt()로 조정하지 않고도 환경 변수 설정을 통해 바꿀 수 있다. (단 M_MXFAST 제외)
환경 변수의 이름은 해당 매개 변수 이름 앞의 'M_'을 'MALLOC_'으로 바꾸고 뒤에는 '_'를 붙인 형태이다.
즉 다음과 같이 호출하면 된다. (bash 기준)

$ export MALLOC_TOP_PAD_=4096
$ ./a.out

이 매개 변수들의 현재 값을 확인하기 위해서는 malloc_get_state() 함수를 이용할 수 있다.
(하지만) 이 함수의 원형은 공개되어 있지만 이 함수가 반환하는 malloc_save_state 구조체는 공개되어 있지 않다.
실제로 위의 구조체는 glibc/malloc/hooks.c에 정의되어 있으므로 그 내용을 복사해서 사용하면 된다.
일반적으로 이 함수는 이러한 내용을 숨긴채 단순히 현재 동적 메모리 할당자의 상태를 저장해 두었다가
나중에 다시 (malloc_set_state() 함수를 통해) 복구하는 용도로만 사용하는 듯 하다.
참고로 이 함수가 반환한 구조체도 malloc()을 통해 동적으로 할당한 것이므로 사용한 후에는 free()해 주어야 한다.

그 외의 동적 메모리 할당자의 상태 정보는 다음과 같은 함수들을 통해서도 알 수 있다.
malloc_stats() : 대략적인 메모리 할당 통계 정보를 stderr로 출력한다.
mallinfo() : 메모리 할당 통계 및 free chunk들에 대한 정보를 mallinfo 구조체로 반환한다.
(특이하게도 포인터가 아닌 구조체 자체를 반환한다!)
malloc_info() : 메모리 할당 통계 및 free chunk들에 대한 정보를 arena 별로 나누어
인자로 주어진 파일 스트림에 XML 형식으로 기록한다. 또 하나의 인자인 options는 반드시 0이어야 한다.

malloc_trim() 함수는 기존의 M_TOP_PAD 매개 변수를 무시하고
인자로 주어진 pad 값만큼의 여유 공간 만을 확보해두고 top chunk의 나머지 영역을 sbrk()를 통해 시스템에 반환한다.
추가로 large bin 내의 4K 이상의 크기를 가지는 chunk들에 대해서도 MADV_DONTNEED를 인자로 하여 madvise()를 호출해서
사용하지 않는 페이지들을 시스템에 반환한다.

malloc_usable_size() 함수는 현재 할당된 메모리 영역에서 사용할 수 있는 크기가 얼마인지를 알려준다.
메모리 할당 요청이 정렬 제한보다 작은 단위의 크기이거나 정확한 크기의 chunk를 찾지 못한 경우에는
실제로 요청한 크기보다 큰 chunk가 할당되었을 수 있다.
(예를 들어 0바이트의 요청에도 16 바이트 크기의 chunk를 반환한다.)

이 함수의 반환값은 일반 chunk인 경우 다음 chunk의 prev_size 필드(footer)까지 이용할 수 있으므로
chunk 크기에서 (size 필드(header)에 필요한) 4바이트를 뺀 크기이며
mmap()으로 할당한 chunk의 경우에는 다음 chunk가 존재하지 않으므로 chunk 크기에서 8을 뺀 크기이고
free()된 chunk인 경우에는 (당연하게도) 0이다.
주의할 점은 fast bin에 속하는 chunk의 경우 free()된 후에도
곧바로 P 플래그가 지워지지 않기 때문에 malloc_usable_size()는 원래의 크기를 반환한다는 것이다.

이 외에도 할당된 메모리 주소를 원하는 위치로 정렬하여 반환하도록 하는 함수들이 있다.
(정렬은 chunk 시작 주소가 아닌 사용자에게 반환되는 메모리 주소 기준으로 이루어진다.)
memalign() 함수는 POSIX 표준 이전에 정의된 함수로 인자로 지정한 정렬 기준과 크기에 맞는 메모리 영역을 할당하여 반환한다.
valloc() 함수는 memalign()에서 정렬 기준을 시스템의 페이지 크기로 한 것이다.
pvalloc() 함수는 memalign()에서 정렬 기준과 크기를 모두 시스템의 페이지 단위로 맞춘 것이다.
posix_memalign() 함수는 memalign과 비슷하지만 반환되는 포인터의 주소를 인자로 넘기도록 하고 에러 코드를 반환한다.

이들은 내부적으로 요청한 크기보다 더 큰 크기로 _int_malloc() 함수를 호출하여 정렬된 위치에 chunk를 새로 할당하고
나머지 영역은 가능하다면 다시 chunk로 만들어서 _int_free() 함수를 통해 곧바로 해지한다.

마지막으로 기존의 malloc(), free() 등의 기본 동작을 override 할 수 있는 여러 hook들이 존재한다.
이 hook 변수에 원하는 함수를 설정하여 통계 정보나 디버깅 정보 등을 수집하는 용도로 사용할 수 있다.
일반적으로 hook 함수는 원하는 작업을 먼저 수행한 뒤 예전 hook을 복원하고 원래의 함수를 호출한 후에
다시 hook을 설정하는 방식으로 작성한다.
자세한 내용은 __malloc_hook(3) man 페이지나 cinsk님의 강좌를 살펴보면 좋을 것이다.
by namhyung | 2009/12/29 18:48 | System | 트랙백(1) | 덧글(2)
트랙백 주소 : http://studyfoss.egloos.com/tb/5209389
☞ 내 이글루에 이 글과 관련된 글 쓰기 (트랙백 보내기) [도움말]
Tracked from tomato_house at 2010/02/09 17:25

제목 : [glibc] 동적 메모리 관리 (3)
[glibc] 동적 메모리 관리 (3)...more

Commented by 초보 at 2010/07/28 16:14
잘보고갑니다. 주옥같은 글이네요.
malloc()과 free()에 대한 개념을 잡을 수 있었습니다^^
Commented by namhyung at 2010/07/29 00:03
좋게 봐 주셔서 감사합니다.. ^^

:         :

:

비공개 덧글

◀ 이전 페이지 다음 페이지 ▶

카테고리
General
Application
System
Kernel
Book
Tips
태그
memory script kernel blktrace bash C build CAaQA3 gcc compiler patch perf emacs x86 CARM algorithm vcs elf awk sed synchronization documentation block-layer glibc git computer-architecture linux binutils SMP scm
전체보기
이글루 파인더

최근 등록된 덧글
http://serbaserbiinfoterkini56..
by cakra at 09/22
informsi yang bagus dan b..
by cakra at 09/16
informsi yang bagus dan be..
by pordanaia at 08/05
최근 등록된 트랙백
Tod's Ferrari Homme
by Tods Pas Cher,Kodak did ..
Mocassin Femme
by Mocassins Homme, I got so..
natural garcinia cambogia
by
rss

skin by jiinny


X