<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Memory on Hammer's Blog</title><link>https://lkic1625.github.io/blog/memory/</link><description>Recent content in Memory on Hammer's Blog</description><generator>Hugo</generator><language>ko-kr</language><copyright>© 조원빈 - All rights reserved</copyright><lastBuildDate>Mon, 02 Nov 2026 15:30:09 +0900</lastBuildDate><atom:link href="https://lkic1625.github.io/blog/memory/index.xml" rel="self" type="application/rss+xml"/><item><title>SRAM의 구조와 용량 확장의 한계</title><link>https://lkic1625.github.io/os-sram/</link><pubDate>Mon, 02 Nov 2026 15:30:09 +0900</pubDate><guid>https://lkic1625.github.io/os-sram/</guid><description>&lt;h2 id="개요">개요&lt;/h2>
&lt;p>여태 DRAM Access는 지속적으로 CPU cycle에서 보자면 높은 latency로 인해 OS에서는 지양해야할 패턴으로 설명했었다. 반대로 SRAM은 L1, L2, L3 정도의 계층형으로 데이터 용량을 어느정도 커버할 수 있었지만, Cache Hit ratio 등 다양한 고민거리와 OS 단에서의 문제를 더욱 만드는 구조였다.&lt;/p>
&lt;p>그러면 반대로 &lt;strong>SRAM의 용량을 더 늘릴 수는 없을까?&lt;/strong> 실제 책에서도 이러한 SRAM 구조는 확장 가능하지 않은 전자공학적 문제가 있다고 설명한다. 간만에 컴구도 훑을 겸 SRAM이 왜 확장 불가능한지 이야기해보자.&lt;/p>
&lt;h2 id="sram의-구조">SRAM의 구조&lt;/h2>
&lt;p>우선 SRAM의 구조를 알아야, 실제 SRAM이 확장이 왜 어렵고 어떠한 trade-off가 있을지 알 수 있다.&lt;/p></description></item><item><title>Swap과 메모리 관리: Linux, TMO, ZRAM</title><link>https://lkic1625.github.io/os-swap/</link><pubDate>Mon, 02 Nov 2026 15:30:04 +0900</pubDate><guid>https://lkic1625.github.io/os-swap/</guid><description>&lt;h2 id="개요">개요&lt;/h2>
&lt;p>swap, 메모리 오프로딩은 물리적으로 부족한 용량 한계를 하위 단계의 메모리로 이동 시키는 기술이다. 이를 이용하여 우리는 가상화의 큰 장점을 확보하였다.
하지만, 이로 인해 생기는 여러 장단점은 명확한 trade-off이다. 우리는 우선 현대 시스템에서 이러한 Swap이 어떻게 구성되어 있는지 보고, 실제 사례를 보며 기존 시스템의 일반적인 솔루션이 가진 한계를 어떻게 해결하려고 하였는지 찾아보자.&lt;/p>
&lt;h2 id="linux">Linux&lt;/h2>
&lt;p>리눅스는 가장 기본적인 방식은 PTE가 어떻게 바뀌는지를 기본으로 설명할 수 있다. x86-64 Linux에서 특정 페이지가 Swap-out 된다면, 해당 페이지를 가리키던 PTE가 정상적인 물리적 메모리를 매핑하는 게 아닌, Swap Entry를 나타내는 값으로 변경된다.
CPU는 메모리 매핑 중에, 물리 페이지 접근이 불가능함을 판단하고, Page Fault를 통해 OS에게 이를 맡긴다. 이를 통해 Swap Entry라면, 데이터 위치에 대한 정보를 가지고 있기에 이 값을 통해 정장적인 물리 주소 매핑을 구할 수 있다. 보통의 구조는 아래와 같다.
참고로, Swap-out에 대한 victim을 구하는 Page Replacement 알고리즘은 Multi-Generational LRU(MGLRU)라는 휴리스틱을 추가한 LRU을 이용한다. 자세한 건 페이지 교체 알고리즘 챕터에서 더 설명하겠다.&lt;/p></description></item><item><title>메모리 할당기: glibc, jemalloc, TCMalloc, Java, Go</title><link>https://lkic1625.github.io/os-memory-allocation/</link><pubDate>Wed, 21 Oct 2026 13:01:48 +0900</pubDate><guid>https://lkic1625.github.io/os-memory-allocation/</guid><description>&lt;h2 id="allocation-관련-정리">Allocation 관련 정리&lt;/h2>
&lt;p>Allocator는 기본적으로, 4가지 정도 존재한다.&lt;/p>
&lt;ol>
&lt;li>얼마나 빨리 할당할 수 있는가,
&lt;ol>
&lt;li>매번 커널 진입이 아닌, 미리 확보한 메모리를 Free List 를 통해 활요하는 Fast Path를 이용&lt;/li>
&lt;/ol>
&lt;/li>
&lt;li>얼마나 적은 메모리를 낭비하는가
&lt;ol>
&lt;li>단편화 문제를 어떻게 해결하는가, 실제 요청보다 더 큰 Block을 할당하거나, 여유 공간은 충분하지만 연속 공간을 효율적으로 반환하기 어려운 경우&lt;/li>
&lt;/ol>
&lt;/li>
&lt;li>동시성 확보를 위한 방식
&lt;ol>
&lt;li>여러 스레드가 요청하는 경우의 contention 관리&lt;/li>
&lt;/ol>
&lt;/li>
&lt;li>언제 메모리를 반환할 것인가.
&lt;ol>
&lt;li>실제 메모리가 다시 쓰일 확률이 높다면 이를 가지고 재사용하는 것이 합당하다
이 네 가지를 통해 실제 설계 철학들을 엿볼 수 있다. 또한, 현대의 메모리 할당기가 서로 배타적인 구현을 하는 것이 아니고, 각 방법에서 핵심 설계 관점을 다르게 보는 것이다.&lt;/li>
&lt;/ol>
&lt;/li>
&lt;/ol>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>Allocator&lt;/th>
 &lt;th>핵심 설계 관점&lt;/th>
 &lt;th>대표적인 기법&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>glibc malloc (ptmalloc 계열)&lt;/td>
 &lt;td>범용성, 호환성&lt;/td>
 &lt;td>Arena, Thread Cache&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>jemalloc&lt;/td>
 &lt;td>단편화 관리, 메모리 사용량 제어&lt;/td>
 &lt;td>Multiple Arenas, Decay, Purging&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>TCMalloc&lt;/td>
 &lt;td>높은 병렬성과 빠른 할당&lt;/td>
 &lt;td>Per-CPU Cache, rseq, Hugepage-aware Allocation&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>mimalloc&lt;/td>
 &lt;td>낮은 경합, Locality, 메모리 효율&lt;/td>
 &lt;td>Free-list Sharding, Eager Purging&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>snmalloc&lt;/td>
 &lt;td>Cross-thread Free의 확장성&lt;/td>
 &lt;td>Message Passing&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Scudo&lt;/td>
 &lt;td>Heap 메모리 안전성&lt;/td>
 &lt;td>Metadata 검증, Quarantine, Randomization&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h3 id="tcache-glibc">tcache, glibc&lt;/h3>
&lt;pre tabindex="0">&lt;code>Thread 1 ── tcache ──┐
Thread 2 ── tcache ──┼── Arenas ── OS
Thread 3 ── tcache ──┘
&lt;/code>&lt;/pre>&lt;p>객체를 할당하고 해제하는데 필요한 정보를 스레드 별로 두어, lock 집중을 막는 방식&lt;/p></description></item><item><title>주소 변환과 Huge Page</title><link>https://lkic1625.github.io/os-address-translation/</link><pubDate>Thu, 15 Oct 2026 01:43:00 +0900</pubDate><guid>https://lkic1625.github.io/os-address-translation/</guid><description>&lt;p>메모리의 사용 방식과 메모리의 실제 Address Translation 에 대해서 설명한다. 이에 대해서는 크게 정리하지 않겠다. MMU라는 하드웨어 구조 장치에서 일어나는 과정이며 이를 이용하는 소프트웨어 아키텍처 등을 알아보자.&lt;/p>
&lt;h2 id="기본적인-주소-변환-과정">기본적인 주소 변환 과정&lt;/h2>
&lt;p>기본적인 translation 과정은 하드웨어 아키텍처와 OS가 함께 협업하며 작업한다. 현대 CPU 아키텍처에서는 MMU의 구성요소로는 TLB(Translation Lookaside Buffer)가 존재한다. TLB는 L1, L2에 존재하며 계층별 캐싱 구조로 이루어져있다. 만약 두 단계에서 모두 Cache miss가 난다면, Page Walker 계층에서 마지막 캐싱 여부를 판단하고, Page Table에서 데이터를 가져온다.&lt;/p></description></item></channel></rss>