mmap과 malloc의 차이
malloc()
- segregation free list 방식을 이용하여 힙 영역 내에서 메모리를 할당해주는 함수
- 리눅스의 경우brk/sbrk 가 메모리 할당.
- 커널의brk 포인터에 incr(상수보장, 음수 X)만큼 크기를 더해서 힙을 늘이거나 줄인다.
- 성공하면 이전의 brk 포인터 값을 리턴한다.
- 실패하면 -1을 리턴하고 errno = ENOMEM 이라고 설정해준다. incr = 0이면 늘어나지 않았으니 현재의 brk 값을 리턴
- sbrk는 페이지 단위로 할당(4KB), 사이즈가 큰 편이라 단편화하여 사용 heap management library.
- segregation free list에서 free node 리스트 별로 관리한다. ⇒ 상수 시간안에 요청완료
- free node 크기가 512바이트보다 작은 경우 그 크기별로 모두 관리되는데, 링크드 리스트 형태로 관리.
16바이트짜리 free node 리스트, 24 바이트짜리 노드 리스트 등. - 그래서 상수 시간에 완료되는 것
- 각 크기에 대한 리스트를 하나 또 따로 들고 있음.
- 이 리스트에는 각 크기가 적혀 있어서 해당 크기의 링크드 리스트로 연결해줌.malloc()의 할당 단위는 최소 8바이트(위의 페이지 할당 단위(4096 바이트)와 비교하면 매우 큰 차이)
- free를 할 때는 coalescing(병합)과정을 통해 인접한 free 노드를 합쳐서 하나의 큰 free 노드를 만든다.
- free node 크기가 512바이트보다 작은 경우 그 크기별로 모두 관리되는데, 링크드 리스트 형태로 관리.
mmap
- 커널에 새 가상 메모리 영역을 생성해줄 것을 요구하는 함수
- 매핑할 메모리의 위치와 크기를 인자로 전달받음
- 메모리에 매핑된 데이터는 파일 입출력 함수를 사용하지 않고 직접 읽고 쓸수 있다는 장점
- mmap()에서는 할당 메모리의 크기가 최소 4KB(사실은 페이지 크기의 배수로 할당)
malloc vs mmap
크기
- mmap은 “가상 메모리”에 매핑하는 함수.
- 할당해야 할 메모리 크기가 크면 mmap()으로 할당. mmap()에서는 페이지 단위(최소 4KB - 4096 Bytes)로 영역을 할당해주는 반면, 그 이하는 malloc()으로 heap에서 할당.
시스템콜
- mmap을 사용하면, 시스템 콜을 호출할 필요가 없음
- mmap()을 쓰면 메모리에 매핑하고 나머지 작업은 해당 mmap에서 반환하는 주소가 가리키는 메모리 영역의 데이터를 대상으로 작업하기 때문에 매번 read 함수로 읽어올 필요가 없다.
해제
- malloc()은 free()를 호출한다고 해서 해당 메모리 자원이 시스템에 바로 반환되지 않는다. 사실 즉시 해제되지않음
- 반면 munmap()의 경우에는 즉시 시스템에 반환됨.
숨겨진 진실
- malloc()은 큰 메모리 블록 요청이 들어오면 내부적으로 mmap()을 써서 메모리를 할당한다.
- mmap()이 malloc()을 포함하는 개념이라기보다 mmap()은 시스템에서 제공하는 저수준 시스템 콜이며 특별한 조건일 때 메모리를 할당하는 효과를 볼 수 있다