Ryotta's Linux 7.0 MM

메모리 관리 서브시스템 완전 분석

Compaction (메모리 조각 모음)

Linux 7.0 메모리 관리 분석 시리즈

개요 (Overview)

Compaction는 리눅스 커널의 외부 단편화(external fragmentation)를 완화하기 위한 메커니즘입니다. Buddy Allocator는 2의 거듭제곱(order) 크기 블록을 할당하는데, 프리 페이지가 충분히 있지만 연속된 high-order 블록이 없는 경우 할당에 실패합니다. Compaction은 이동 가능한(movable) 페이지를 zone의 한쪽 끝으로 옮기고, 반대쪽 끝의 프리 페이지들을 병합하여 high-order 블록을 생성합니다.

Compaction의 핵심은 page migration에 의존합니다. 두 개의 스캐너가 zone의 양쪽 끝에서 서로를 향해 이동합니다: migrate scanner는 이동 가능한 페이지를 탐색하고, free scanner는 프리 페이지를 탐색합니다. 두 스캐너가 만나면 compaction이 완료됩니다. 커널은 Direct compaction (할당 실패 시 즉시 실행), Background compaction (kcompactd 데몬), Proactive compaction (백그라운드 자동 단편화 해소, 커널 5.9+) 세 가지 모드를 지원합니다. 커널 6.15부터는 defrag_mode sysctl이 추가되어 페이지 할당자가 단편화 회피를 적극 수행할 수 있습니다.

일상 비유: Compaction는 주차장 정리와 비슷합니다. 주차장에 빈 자리가 충분하지만 차들이 흩어져 있어大型 버스(연속 4MB 블록)를 주차할 수 없는 상황입니다. 정비사(migrate scanner)가 한쪽 끝의 차(movable 페이지)를 모두 옮기고, 반대쪽 끝의 빈 자리(free scanner)를 모으면 큰 버스를 주차할 수 있는 연속 공간이 생깁니다.
소스 파일 경로:
```
mm/compaction.c ← Compaction 핵심 로직 (3334줄)
include/linux/compaction.h ← enum compact_priority, enum compact_result 정의
mm/internal.h ← struct compact_control, struct capture_control 정의
include/linux/mmzone.h ← zone 구조체 내 compaction 캐시 필드
```

빠른 점검 명령

# Compaction 트리거 (전체 시스템)
echo 1 > /proc/sys/vm/compact_memory

# NUMA 노드별 compaction 트리거
echo 1 > /sys/devices/system/node/node0/compact

# 현재 compaction 통계
cat /proc/vmstat | grep -E "compact_|kcompactd"

# Compaction deferred 상태 확인
cat /proc/vmstat | grep "compact_defer_shift"

# 외부 단편화 지수 확인
cat /proc/extfraginfo

# Proactive compaction 활성화/비활성화
cat /proc/sys/vm/compaction_proactiveness   # 0~100 (기본 20)

# 단편화 점수 확인 (노드별)
cat /sys/kernel/mm/compaction/proactiveness

# defrag_mode — 단편화 회피 모드 (커널 6.15+)
cat /proc/sys/vm/defrag_mode   # 0: 비활성 (기본), 1: 적극적 단편화 회피

# kcompactd 스레드 상태 확인
ps -eo pid,comm | grep kcompactd

# zone별 compaction 캐시 PFN 확인
cat /proc/zoneinfo | grep -E "compact_cached"

핵심 자료구조

1. `struct compact_control` — Compaction 제어 구조체

Compaction의 모든 상태와 파라미터를 담당하는 핵심 구조체입니다. direct compaction, kcompactd, /proc 트리거 등 모든 진입점에서 사용됩니다.

// mm/internal.h:950-988
struct compact_control {
    struct list_head freepages[NR_PAGE_ORDERS]; // 프리 페이지 목록 (order별)
    struct list_head migratepages;  // 이동 대상 페이지 목록
    unsigned int nr_freepages;      // 격리된 프리 페이지 수
    unsigned int nr_migratepages;   // 이동 대상 페이지 수
    unsigned long free_pfn;         // free scanner 시작 위치
    unsigned long migrate_pfn;      // migrate scanner 위치 (in/out)
    unsigned long fast_start_pfn;   // 선형 스캔 시작 위치
    struct zone *zone;              // 대상 zone
    unsigned long total_migrate_scanned; // 총 이동 스캔 수
    unsigned long total_free_scanned;    // 총 프리 스캔 수
    unsigned short fast_search_fail;     // fast search 실패 수
    short search_order;             // fast search 시작 order
    const gfp_t gfp_mask;          // GFP 마스크
    int order;                      // 할당 대상 order
    int migratetype;                // 할당 대상 migratetype
    const unsigned int alloc_flags; // 할당 플래그
    const int highest_zoneidx;      // 최대 zone 인덱스
    enum migrate_mode mode;         // Async/Sync/Sync_light
    bool ignore_skip_hint;          // skip 힌트 무시 여부
    bool no_set_skip_hint;          // skip 힌트 설정 안 함
    bool ignore_block_suitable;     // 적합하지 않은 블록 무시
    bool direct_compaction;         // true = direct, false = kcompactd
    bool proactive_compaction;      // true = proactive
    bool whole_zone;                // 전체 zone 스캔 여부
    bool contended;                 // lock 경쟁 발생 여부
    bool finish_pageblock;          // 현재 pageblock 스캔 완료 여부
    bool alloc_contig;              // alloc_contig_range 할당 여부
};

주요 필드 설명:

  • freepages[NR_PAGE_ORDERS]: free scanner가 격리한 프리 페이지를 order별로 분리하여 보관
  • migratepages: migrate scanner가 격리한 이동 대상 페이지 목록
  • migrate_pfn / free_pfn: 두 스캐너의 현재 위치. compaction이 진행되면서 서로를 향해 이동
  • mode: MIGRATE_ASYNC (논블로킹), MIGRATE_SYNC_LIGHT (기본), MIGRATE_SYNC (완전 동기)
  • direct_compaction: direct compaction인지 kcompactd/background인지 구분
  • 2. `struct capture_control` — Direct compaction 캡처 구조체

    Direct compaction 중 IRQ 핸들러가 프리 페이지를 반환하면 즉시 캡처하여 할당에 활용합니다.

    // mm/internal.h:994-997
    struct capture_control {
        struct compact_control *cc;  // compaction 제어 구조체 포인터
        struct page *page;           // 캡처된 프리 페이지 (할당 성공 시)
    };

    compact_zone_order()에서 current->capture_control에 설정하고, IRQ에서 페이지 해제 시 __free_pages_core()가 이 구조체를 통해 페이지를 캡처합니다.

    3. `enum compact_priority` — Compaction 우선순위

    // include/linux/compaction.h:9-17
    enum compact_priority {
        COMPACT_PRIO_SYNC_FULL,        // 0: 완전 동기 (최고 우선순위)
        MIN_COMPACT_PRIORITY = COMPACT_PRIO_SYNC_FULL,
        COMPACT_PRIO_SYNC_LIGHT,       // 1: 가벼운 동기 (기본)
        MIN_COMPACT_COSTLY_PRIORITY = COMPACT_PRIO_SYNC_LIGHT,
        DEF_COMPACT_PRIORITY = COMPACT_PRIO_SYNC_LIGHT,
        COMPACT_PRIO_ASYNC,            // 2: 비동기 (최저 우선순위)
        INIT_COMPACT_PRIORITY = COMPACT_PRIO_ASYNC
    };

    4. `enum compact_result` — Compaction 결과 코드

    // include/linux/compaction.h:21-56
    enum compact_result {
        COMPACT_NOT_SUITABLE_ZONE,    // 내부: zone 적합하지 않음
        COMPACT_SKIPPED,              // compaction 시작 안 함
        COMPACT_DEFERRED,             // 이전 실패로 인해 연기됨
        COMPACT_NO_SUITABLE_PAGE,     // 내부: 적합 프리 페이지 없음
        COMPACT_CONTINUE,             // 계속 진행
        COMPACT_COMPLETE,             // 전체 zone 스캔 완료
        COMPACT_PARTIAL_SKIPPED,      // 일부 영역만 스캔
        COMPACT_CONTENDED,            // lock 경쟁으로 중단
        COMPACT_SUCCESS,              // 할당 성공
    };

    핵심 함수

    1. `try_to_compact_pages()` — Direct compaction 진입점

    할당 실패 시 page allocator에서 직접 호출하는 메인 진입 함수입니다. zonelist의 각 zone에 대해 compact_zone_order()를 순차적으로 호출합니다.

    // mm/compaction.c:2814-2880
    enum compact_result try_to_compact_pages(gfp_t gfp_mask, unsigned int order,
            unsigned int alloc_flags, const struct alloc_context *ac,
            enum compact_priority prio, struct page **capture)
    {
        // 1. gfp_compaction_allowed() 검사
        // 2. zonelist 순회
        for_each_zone_zonelist_nodemask(zone, z, ac->zonelist, ...) {
            // cpuset 검사
            // compaction_deferred() 검사 → 연기된 zone 건너뜀
            status = compact_zone_order(zone, order, ...);
            if (status == COMPACT_SUCCESS) break;
            // ASYNC에서 need_resched() 또는 fatal signal → 중단
        }
    }

    분기 로직:

  • gfp_compaction_allowed() 실패 → 즉시 COMPACT_SKIPPED
  • compaction_deferred() 참 → COMPACT_DEFERRED (이전 실패로 연기)
  • COMPACT_SUCCESS → 반복 즉시 중단 (할당 성공 예상)
  • COMPACT_COMPLETE / COMPACT_PARTIAL_SKIPPEDdefer_compaction() 호출
  • 2. `compact_zone()` — Compaction 코어 로직

    하나의 zone에 대한 compaction을 수행하는 핵심 함수입니다. migrate/free 스캐너를 교대로 실행하고, 이동 가능한 페이지를 격리하여 migration합니다.

    // mm/compaction.c:2510-2747
    static enum compact_result compact_zone(struct compact_control *cc,
                                            struct capture_control *capc)
    {
        // 1. 스캐너 초기 위치 설정 (캐시된 PFN 또는 zone 끝)
        // 2. while (compact_finished() == COMPACT_CONTINUE) 반복:
        //    a. isolate_migratepages(cc) → 이동 대상 페이지 격리
        //    b. migrate_pages() → compaction_alloc/free 콜백으로 실제 이동
        //    c. check_drain: order > 0이면 lru_add_drain_cpu_zone()
        // 3. 프리 페이지 해제 및 캐시 업데이트
    }

    핵심 분기:

  • compaction_suit_allocation_order() 실패 → 즉시 반환 (watermark 미충족)
  • compaction_restarting()__reset_isolation_suitable() (스킵 힌트 초기화)
  • isolate_migratepages() 결과에 따라 ISOLATE_ABORT / ISOLATE_NONE / ISOLATE_SUCCESS 분기
  • migrate_pages() 실패 → -ENOMEMCOMPACT_CONTENDED, ASYNC 실패 시 finish_pageblock 설정
  • 3. `compact_finished()` — Compaction 완료 검사

    compaction이 끝났는지判断하는 함수입니다. 두 스캐너가 만났는지, 프리 페이지가 충분한지, watermark를 만족하는지 확인합니다.

    // mm/compaction.c:2234-2355
    static enum compact_result __compact_finished(struct compact_control *cc)
    {
        // 1. compact_scanners_met(): 두 스캐너가 만나면 COMPACT_COMPLETE/PARTIAL_SKIPPED
        // 2. proactive_compaction: fragmentation 점수로 판단
        //    - 점수 > wmark_low → COMPACT_CONTINUE
        //    - 점수 ≤ wmark_low → COMPACT_SUCCESS
        // 3. defrag_mode && kcompactd: NR_FREE_PAGES_BLOCKS 기준 watermark 검사
        // 4. direct compactor: free_area에서 대상 migratetype의 프리 페이지 확인
        //    - 해당 migratetype 프리 → COMPACT_SUCCESS
        //    - MIGRATE_MOVABLE → CMA fallback 허용
        //    - steal 가능하면 COMPACT_SUCCESS
        // 5. contended || fatal_signal → COMPACT_CONTENDED
    }

    핵심 분기:

  • compact_scanners_met()reset_cached_positions()COMPACT_COMPLETE
  • proactive_compactionfragmentation_score_zone() vs fragmentation_score_wmark() 비교
  • defrag_mode 활성화 시 NR_FREE_PAGES_BLOCKS 기반 watermark 검사 (high watermark 요구)
  • free_area_empty() 실패 → find_suitable_fallback()으로 steal 가능성 검사
  • 4. `isolate_migratepages_block()` — 페이지 격리

    하나의 pageblock 내에서 이동 가능한 페이지를 격리하는 함수입니다. LRU 목록에서 페이지를 제거하고 cc->migratepages 목록에 추가합니다.

    // mm/compaction.c:836-1308
    static int isolate_migratepages_block(struct compact_control *cc,
            unsigned long low_pfn, unsigned long end_pfn, isolate_mode_t mode)
    {
        for (; low_pfn < end_pfn; low_pfn++) {
            // PageHuge → isolate_or_dissolve_huge_folio()
            // PageBuddy → 건너뜀
            // PageCompound && !alloc_contig → skip_isolation_on_order() 검사
            // PageLRU → folio 격리
            //   - too_many_isolated() 검사 (LRU 격리 제한)
            //   - ISOLATE_ASYNC_MIGRATE → writeback/dirty 페이지 제외
            //   - folio_test_clear_lru() → LRU에서 제거
            //   - COMPACT_CLUSTER_MAX 도달 시 중단
        }
    }

    5. `compaction_alloc()` / `compaction_free()` — Migration 콜백

    migrate_pages()가 호출하는 콜백 함수입니다. compaction_alloc()은 프리 페이지 목록에서 대상 페이지를 제공하고, compaction_free()는 실패 시 프리 페이지로 반환합니다.

    // mm/compaction.c:1797-1848
    static struct folio *compaction_alloc_noprof(struct folio *src, unsigned long data)
    {
        struct compact_control *cc = (struct compact_control *)data;
        // 1. freepages[]에서 알맞은 order의 프리 페이지 탐색
        // 2. 없으면 isolate_freepages() 호출하여 추가 격리
        // 3. 큰 order 블록을 split하여 요청 order로 제공
        // 4. nr_freepages, nr_migratepages 갱신
    }
    
    static void compaction_free(struct folio *dst, unsigned long data)
    {
        // 실패한 페이지를 freepages[]로 반환
    }

    6. `kcompactd()` — 백그라운드 Compaction 데몬

    각 NUMA 노드마다 하나씩 실행되는 커널 스레드입니다. proactive compaction과 요청 기반 compaction을 처리합니다.

    // mm/compaction.c:3165-3231
    static int kcompactd(void *p)
    {
        pg_data_t *pgdat = (pg_data_t *)p;
        long default_timeout = msecs_to_jiffies(HPAGE_FRAG_CHECK_INTERVAL_MSEC);
        long timeout = default_timeout;
    
        current->flags |= PF_KCOMPACTD;
        set_freezable();
    
        while (!kthread_should_stop()) {
            // 1. proactiveness 비활성화 시 timeout = MAX_SCHEDULE_TIMEOUT
            // 2. wait_event_freezable_timeout()으로 대기
            // 3. kcompactd_work_requested() → kcompactd_do_work() 실행
            // 4. should_proactive_compact_node() → compact_node() 실행
            //    - fragmentation_score_node() > wmark_high → proactive 시작
            //    - 점수 개선 없으면 timeout 증가 (지연)
            timeout = default_timeout;
        }
    }

    proactive compaction 분기:

  • sysctl_compaction_proactiveness == 0 → timeout = MAX_SCHEDULE_TIMEOUT (비활성)
  • fragmentation_score_node() > wmark_highcompact_node() 실행
  • 점수 개선 실패 → timeout << COMPACT_MAX_DEFER_SHIFT (최대 64배 지연)
  • 7. `compact_zone_order()` — compact_control 초기화

    Direct compaction에서 compact_control 구조체를 초기화하는 함수입니다. 우선순위(prio)에 따라 mode, whole_zone, ignore_skip_hint 등이 달라집니다.

    // mm/compaction.c:2749-2768
    static enum compact_result compact_zone_order(struct zone *zone, int order,
            gfp_t gfp_mask, enum compact_priority prio,
            unsigned int alloc_flags, int highest_zoneidx,
            struct page **capture)
    {
        struct compact_control cc = {
            .order = order,
            .search_order = order,
            .gfp_mask = gfp_mask,
            .zone = zone,
            .mode = (prio == COMPACT_PRIO_ASYNC) ?
                        MIGRATE_ASYNC : MIGRATE_SYNC_LIGHT,
            .alloc_flags = alloc_flags,
            .highest_zoneidx = highest_zoneidx,
            .direct_compaction = true,
            .whole_zone = (prio == MIN_COMPACT_PRIORITY),        // 최고 우선순위에서 전체 zone 스캔
            .ignore_skip_hint = (prio == MIN_COMPACT_PRIORITY),  // skip 힌트 무시
            .ignore_block_suitable = (prio == MIN_COMPACT_PRIORITY) // 적합 블록 무시
        };
        struct capture_control capc = {
            .cc = &cc,
            .page = NULL,
        };
        // capture_control을 current에 설정 — IRQ에서 프리 페이지 캡처 가능
        WRITE_ONCE(current->capture_control, &capc);
        ret = compact_zone(&cc, &capc);
        ...
    }

    compact_control 초기화 분기:

  • COMPACT_PRIO_ASYNCMIGRATE_ASYNC (논블로킹, 부분 스캔)
  • COMPACT_PRIO_SYNC_LIGHT (기본) → MIGRATE_SYNC_LIGHT (조건부 동기)
  • MIN_COMPACT_PRIORITYwhole_zone=true, ignore_skip_hint=true (전체 zone, skip 무시)

  • 호출 흐름

    Direct Compaction 흐름

    __alloc_pages() 실패
      └→ __alloc_pages_slowpath()
           └→ __alloc_pages_direct_reclaim() 실패
                └→ __alloc_pages_direct_compact()
                     └→ try_to_compact_pages()           ← Direct compaction 진입
                          └→ compact_zone_order()        ← compact_control 초기화
                               └→ compact_zone()          ← 코어 루프
                                    ├→ compaction_suit_allocation_order()  ← watermark 검사
                                    ├→ isolate_migratepages()             ← 이동 대상 격리
                                    │    └→ isolate_migratepages_block()  ← pageblock 단위
                                    ├→ migrate_pages()                    ← 실제 이동
                                    │    ├→ compaction_alloc()            ← 대상 페이지 할당
                                    │    └→ compaction_free()             ← 실패 시 반환
                                    └→ compact_finished()                 ← 완료 검사

    kcompactd 흐름

    wakeup_kcompactd()                    ← page allocator에서 호출
      └→ wake_up_interruptible()
    
    kcompactd() 스레드 기상
      ├→ kcompactd_do_work()              ← 일반 compaction
      │    └→ compact_zone()
      └→ should_proactive_compact_node()  ← proactive compaction
           └→ compact_node()              ← 전체 zone 순회
                └→ compact_zone()

    Free Scanner ↔ Meet Scanner 구조

    Zone 시작 (low_pfn)
      │
      │  ← migrate scanner →
      │  (migrate_pfn: 앞에서 뒤로)
      │
      │  이동 가능한 페이지 격리 → migratepages
      │
      │         ← free scanner
      │  (free_pfn: 뒤에서 앞으로)
      │
      │  프리 페이지 격리 → freepages[]
      │
      └─ 두 스캐너가 만나면 compaction 종료

    조건별 비교

    Compaction 모드 비교

    항목MIGRATE_ASYNCMIGRATE_SYNC_LIGHTMIGRATE_SYNC
    **블로킹**비동기 (논블로킹)조건부 동기완전 동기
    **우선순위**COMPACT_PRIO_ASYNCDEF_COMPACT_PRIORITYMIN_COMPACT_PRIORITY
    **스캐너 범위**부분 스캔부분 스캔전체 zone (whole_zone)
    **skip_hint**사용사용무시 (ignore_skip_hint)
    **적합 블록 무시**아님아님무시 (ignore_block_suitable)
    **isolation stride**COMPACT_CLUSTER_MAX11
    **lock 경쟁 시**trylock → 중단lock 대기lock 대기

    Compaction 트리거 경로 비교

    경로진입 함수compact_control 설정주요 특징
    **Direct compaction**`try_to_compact_pages()`direct_compaction=true, whole_zone=false (prio별)할당 실패 시 즉시 실행, capture_control로 프리 페이지 캡처
    **kcompactd**`kcompactd_do_work()`direct_compaction=false, whole_zone=false백그라운드 실행, watermark_high 기준
    **Proactive**`compact_node()`proactive_compaction=true, whole_zone=truefragmentation 점수 기반, kcompactd 내부
    **compact_memory**`compact_nodes()`order=-1, whole_zone=true, ignore_skip_hint=true/proc/sys/vm/compact_memory 트리거
    **NUMA node compact**`compact_node()`order=-1, whole_zone=true/sys/devices/system/node/nodeX/compact 트리거

    Compaction 결과 비교

    결과의미후속 동작
    `COMPACT_SUCCESS`할당 가능한 프리 블록 확보할당 시도
    `COMPACT_CONTINUE`계속 진행 가능반복 루프 계속
    `COMPACT_COMPLETE`전체 zone 스캔 완료`defer_compaction()` (non-MIN)
    `COMPACT_PARTIAL_SKIPPED`부분 스캔만 완료`defer_compaction()`
    `COMPACT_DEFERRED`이전 실패로 연기건너뜀
    `COMPACT_SKIPPED`compaction 불가 (watermark 미충족 등)다음 zone으로
    `COMPACT_CONTENDED`lock 경쟁으로 중단즉시 반환

    스캐너 skip 힌트 동작 비교

    조건skip 설정skip 검사설명
    격리된 페이지 없음`set_pageblock_skip()``isolation_suitable()`빈 블록은 향후 스캔에서 건너뜀
    isolated == 0 && finish_pageblock`set_pageblock_skip()``isolation_suitable()`완료 시에도 설정
    ignore_skip_hint=true설정 안 함항상 통과MIN_COMPACT_PRIORITY에서 사용
    no_set_skip_hint=true설정 안 함설정isolated 포지션 업데이트 시
    pageblock_skip_persistent설정 안 함항상 건너뜀compound >= pageblock_order

    defrag_mode 동작 비교 (커널 6.15+)

    defrag_modekcompactd 동작compact_finished 기준일반 할당자 영향
    `0` (기본)일반 compact_zonefree_area에서 프리 페이지 확인기존대로 동작
    `1` (적극적)NR_FREE_PAGES_BLOCKS 기준high watermark 요구할당 시 compaction 회피 강화

    증상별 진단

    minzkn.com의 "메모리 운영 플레이북"과 유사하게, compaction 관련 증상별 진단 포인트를 정리합니다.

    증상우선 점검권장 조치
    **고차 페이지 할당 실패** (THP 2MB 등)`/proc/buddyinfo`, `cat /proc/vmstat \grep compact`compaction 튜닝, hugepage 정책 점검, `defrag_mode=1` 시도
    **compact_stall 급증**`cat /proc/vmstat \grep compact_stall`THP `defrag` 모드를 `madvise`로 변경, proactive_compactiveness 조정
    **compact_fail > compact_success**`cat /proc/vmstat \grep compact_fail`단편화 심화 상태 — `echo 1 > /proc/sys/vm/compact_memory` 수동 트리거
    **kcompactd 과도한 CPU 사용**`top -H -p $(pgrep kcompactd)``compaction_proactiveness` 감소 (0으로 비활성화 가능)
    **khugepaged 과도한 CPU**`top -H -p $(pgrep khugepaged)`THP defrag를 `madvise`로 변경, khugepaged 스캔 주기 조정
    **defer_compaction 반복**`cat /proc/vmstat \grep defer`메모리 부족 상태 — 회수 경로 점검, 불필요한 메모리 사용 해소
    **zone 내 fragmentation index 높음**`cat /proc/extfraginfo`memcg 제한 재조정, CMA 영역 확보, zonelist 순서 변경
    # compaction 관련 통계 전체 확인 스크립트
    echo "=== Compaction 통계 ==="
    cat /proc/vmstat | grep -E "compact_|kcompactd|defer"
    echo ""
    echo "=== buddyinfo (단편화 상태) ==="
    cat /proc/buddyinfo
    echo ""
    echo "=== fragmentation index ==="
    cat /proc/extfraginfo
    echo ""
    echo "=== sysctl 파라미터 ==="
    sysctl vm.compaction_proactiveness vm.compact_memory vm.extfrag_threshold 2>/dev/null
    echo ""
    echo "=== defrag_mode (커널 6.15+) ==="
    cat /proc/sys/vm/defrag_mode 2>/dev/null || echo "해당 없음"

    관련 문서

  • Buddy Allocator — 프리 페이지 관리 및 buddy 병합
  • Huge Pages / THP — THP를 위한 compaction 활용
  • CMA — CMA를 위한 compaction 활용
  • Migration — compaction의 핵심 메커니즘인 page migration
  • 페이지 회수 — vmscan과의 연계
  • 메모리 관리 개요 — 전체 아키텍처 이해

  • SVG 다이어그램

    Compaction 전체 호출 흐름

    Compaction 호출 흐름

    Compaction 자료구조 관계도

    Compaction 자료구조