처리중입니다. 잠시만 기다려주세요.
TTJ 코딩클래스
정규반 단과 자료실 테크 뉴스 코딩 퀴즈
테크 뉴스
Hacker News 2026.07.24 48

malloc(10)을 했는데 왜 메모리는 더 쓰일까 — 메모리 할당자의 속사정

Hacker News 원문 보기
malloc(10)을 했는데 왜 메모리는 더 쓰일까 — 메모리 할당자의 속사정

C 언어를 처음 배울 때 우리는 malloc(10)이 힙 메모리 10바이트를 떼어준다고 배워요. 그런데 실제로는 거의 항상 그보다 많은 메모리가 사용되거든요. 요청한 것보다 더 쓰는 이유가 뭘까요? 한 개발자가 이 질문을 파고든 글을 올렸는데, malloc의 속사정을 이해하는 데 정말 좋은 소재라 정리해 봤어요.

free는 크기를 모른다는 사실에서 시작해요

첫 번째 이유는 의외로 free() 함수에 있어요. free(ptr)를 호출할 때 우리는 포인터만 넘기지, 크기를 넘기지 않잖아요. 그럼 할당자는 이 블록이 몇 바이트짜리인지 어떻게 알까요? 답은 간단해요. malloc이 메모리를 내줄 때 크기 정보를 몰래 어딘가에 적어두는 거예요. glibc(리눅스의 표준 C 라이브러리)의 경우, 여러분이 받는 포인터 바로 앞에 이 블록의 크기가 적힌 헤더가 붙어 있거든요. 즉 malloc(10)을 하면 최소한 10바이트에 헤더 공간을 더한 만큼이 필요한 거죠. 참고로 이 구조 때문에 배열 범위를 살짝 벗어나 앞쪽에 값을 쓰면 헤더가 깨지면서 프로그램이 엉뚱한 곳에서 죽는, 그 유명한 힙 손상 버그가 생기는 거예요.

정렬: 주소는 아무 데나 시작할 수 없어요

두 번째 이유는 정렬(alignment)이에요. 이게 뭐냐면, CPU가 메모리를 효율적으로 읽으려면 데이터가 특정 배수의 주소에서 시작해야 한다는 규칙이에요. x86-64 리눅스에서 malloc은 어떤 타입의 데이터가 와도 문제없도록 반환 주소를 16바이트 배수로 맞춰주거든요. 그래서 malloc(10)을 해도 실제 확보되는 공간은 16바이트 단위로 올림 처리돼요. 10바이트를 달라고 했는데 알고 보면 그보다 큰 덩어리가 잡혀 있는 이유 중 하나죠.

최소 크기와 사이즈 클래스

세 번째, 할당자에는 최소 블록 크기가 있어요. glibc에서는 아무리 작게 요청해도 청크 하나가 최소 32바이트 정도를 차지하거든요. 왜냐하면 그 블록이 free된 뒤에는 그 자리에 '비어 있는 블록 목록'을 잇는 포인터들을 저장해야 해서, 포인터 두 개가 들어갈 공간은 반드시 필요하기 때문이에요. malloc(1)을 백만 번 호출하면 1MB가 아니라 30MB 넘게 쓰게 되는 이유가 여기 있어요.

네 번째로 '사이즈 클래스'라는 개념이 있는데요. 할당자는 요청 크기를 미리 정해둔 등급(16, 32, 48, 64바이트...)으로 반올림해서 관리해요. 이렇게 하면 같은 등급의 빈 블록을 재사용하기 쉬워서 할당 속도가 빨라지고, 메모리 곳곳에 못 쓰는 자투리가 생기는 단편화도 줄거든요. glibc의 tcache와 fastbin, 구글의 tcmalloc, 페이스북이 키운 jemalloc, 마이크로소프트의 mimalloc까지, 현대 할당자들의 성능 경쟁은 사실상 이 사이즈 클래스와 캐싱 전략 싸움이에요.

큰 요청은 아예 다른 길로 가요

크기가 큰 요청은 처리 방식 자체가 달라요. glibc 기준으로 약 128KB를 넘는 요청은 힙에서 떼어주는 대신 mmap이라는 시스템 콜로 운영체제에서 직접 페이지를 받아오거든요. 페이지는 보통 4KB 단위라서, 130KB를 요청하면 4KB 배수로 올림된 크기가 통째로 잡혀요. 내가 실제로 얼마를 받았는지 궁금하면 malloc_usable_size() 함수로 확인해 볼 수 있는데, 이 여분 공간을 믿고 쓰는 코드는 이식성이 없으니 호기심 용도로만 쓰는 게 좋아요.

한국 개발자에게 주는 시사점

'나는 C 안 쓰는데요' 하실 수 있지만, 이 원리는 모든 언어에 적용되거든요. Java의 JVM도, Go 런타임도, Python 인터프리터도 내부적으로 비슷한 구조의 할당자를 쓰고 있어요. 메모리 프로파일링을 할 때 계산상 사용량보다 실제 메모리(RSS)가 훨씬 크게 나오는 이유, 작은 객체를 수백만 개 만들면 예상보다 메모리가 폭발하는 이유가 전부 여기서 나와요. 그래서 고성능 코드에서는 작은 할당을 반복하는 대신 큰 배열을 한 번에 잡거나 객체 풀을 쓰는 거죠.

마무리

정리하면, malloc은 크기 기록, 정렬, 최소 크기, 사이즈 클래스라는 네 가지 이유로 항상 요청보다 넉넉하게 할당한다는 이야기예요. 여러분은 메모리 사용량 때문에 고생해 본 경험이 있으신가요? 예상보다 메모리를 많이 먹어서 원인을 추적했던 사연이 있다면 나눠주세요.


🔗 출처: Hacker News

이 뉴스가 유용했나요?

이 기술을 직접 배워보세요

파이썬으로 자동화를 시작해보세요

파이썬 기초부터 자동화까지 실전 강의.

파이썬 강의 보기

"비전공 직장인인데 반년 만에 수익 파이프라인을 여러 개 만들었습니다"

실제 수강생 후기
  • 비전공자도 6개월이면 첫 수익
  • 20년 경력 개발자 직강
  • 자동화 프로그램 + 소스코드 제공

매일 AI·개발 뉴스를 받아보세요

주요 테크 뉴스를 매일 아침 이메일로 전해드립니다.

스팸 없이, 언제든 구독 취소 가능합니다.