# 1. 임베디드 자원 제약 환경 하의 컴파일 메모리 병목 통제 수단

가용 메모리(RAM)와 스토리지 대역폭이 극단적으로 제한된 임베디드 보드(예: Raspberry Pi, NVIDIA Jetson 시리즈 등) 환경에서 ROS 2 기반 자율 에이전트 소프트웨어 스택을 크로스 컴파일(Cross-compile)하거나 네이티브 빌드(Native Build)하는 경우, CPU 처리 성능보다 메모리 용량의 한계가 빌드 실패를 유발하는 주된 원인으로 작용한다. C++ 템플릿 메타 프로그래밍(Template Meta-programming)이 다수 포함된 방대한 ROS 2 코어 패키지들의 병렬 컴파일은 기하급수적인 힙(Heap) 메모리 요구량을 동반하며, 이는 곧장 시스템 리소스 고갈 파닉(OOM, Out-Of-Memory Panic) 현상을 초래한다. 따라서 Colcon 빌드 시스템에서는 이러한 메모리 병목(Memory Bottleneck) 구간을 극복하기 위한 다각도의 통제 수단이 적용되어야 한다.

1.1 Colcon 동시성 레벨 하향(Downgrade) 제어 인자 적용

메모리 포화를 방지하는 최우선적인 수단은 Colcon이 운용하는 익스큐터(Executor)의 풀 스레드 수, 즉 패키지 수준의 병렬성을 하드웨어 제약 조건 이하로 통제선(Throttle)을 설정하는 것이다.

  • --executor-config 패러미터 튜닝: Colcon의 기본 동작 모델인 논리적 코어 수의 비례적 1:1 매핑을 해제해야 한다. --executor-config max_workers=1과 같이 워커 스레드의 최대 가용 개수를 1개 혹은 2개 수준으로 강제 하향 조정함으로써, 시간당 메모리에 적재되는 컴파일러 인스턴스(Compiler Instance)의 총량을 물리적 한계치 이내로 제약(Constraint)한다.
  • 순차적 연산(Sequential Operation) 모드: 병렬 그래프 탐색을 근본적으로 제한하고 온전히 순차 빌드 모드로 전환하기 위한 --sequential 인자가 제공된다. 이는 DAG 스케줄링이 유발하는 복수의 종속성 없는 노드 동시 확장을 억제하여, 피크 메모리(Peak Memory) 소비량의 편차(Variance)를 극소화한다.

1.2 하위 빌드 시스템(CMake/Make) 컴파일 유닛 병렬화 통제

Colcon 워커 스레드가 1개로 제한되었다 하더라도, 해당 워커가 하위 빌드 도구에 실행을 이양(Delegation)할 때 기본적으로 활용되는 패키지 내부 병렬 컴파일 메커니즘을 억제하지 않으면 OOM 에러는 재차 발생한다.

  • MAKEFLAGS 환경 변수 무효화: CMake가 내부적으로 호출하는 Make나 Ninja는 시스템의 코어 수에 비례하여 -j (Jobs) 파라미터를 자동 추론하려는 경향이 있다. 메인 쉘 환경 변수나 Colcon의 __override 인자(--cmake-args -j1 등)를 통해 컴파일 단위에 대한 병렬성 플래그를 -j1 (단일 스크립트 실행)로 명시적 주입해야 한다.
  • 메모리 집약적(Memory-intensive) 최적화 옵션 억제: GCC 및 Clang 컴파일러가 LTO(Link Time Optimization)와 같은 고도의 코드 결합 최적화나 복잡한 템플릿 인스턴스화를 수행할 때, 단일 목적 파일(.o)의 메모리 점유율이 기가바이트(GB) 단위를 초과하는 현상이 보고된다. 파라미터 튜닝에 추가하여 CMake 측에서 -O0 또는 템플릿 깊이(Depth)를 제약하는 플래그(-ftemplate-depth)를 환경 변수(CXXFLAGS)에 주입하여 컴파일러 프로세스 자체의 메모리 점유 가중치를 완화할 필요가 있다.

1.3 컴파일러 링킹(Linking) 단계의 메모리 풋프린트 관리

임베디드 타겟 빌드 과정 중 가장 심각한 메모리 피크(Memory Peak)는 수십 개의 목적 파일을 하나의 공유 라이브러리(.so)나 바이너리로 링킹하는 시점에 집중된다. 이 구간의 메모리 풋프린트를 감소시키지 못하면 OOM-killer 개입이 필연적이다.

  • 심볼(Symbol) 데이터 감축 및 분할 링킹: 컴파일러 최적화 수준을 조정하여 목적 파일(Object File) 내에 기록되는 방대한 양의 디버그 심볼(-g)을 차단하거나 정적(Static) 라이브러리 형식 중심의 부분적 링킹(Partial Linking) 모델로 유도하는 것이 효과적이다.
  • 메모리 최적화 링커 사용: 빌드 도구를 구성할 때, 시스템 기본 링커(BfD linker) 대비 메모리 파편화(Fragmentation)가 적고 동작 효율이 최적화된 서드파티 링커(예: LLVM-의 lld 또는 GNU gold 링커)를 교체 사용하도록 CMake의 툴체인(Toolchain) 파일에 오버라이드 룰(Override Rule)을 선언함으로써 링킹 시점의 일시적인 동적 메모리 폭증 현상을 구조적으로 지연 방어할 수 있다.

1.4 물리적 가상 메모리(Swap Space)의 보루적 확장 체계 마련

상기한 소프트웨어 수준의 동시성 통제 논리만으로 극단적인 메모리 한계를 우회할 수 없는 경우가 존재한다. 특히 거대 생태계 패키지(예: ros2_control, nav2)는 단일 파일 단위 처리라 할지라도 수백 MB 이상의 메모리가 필수적으로 수반된다.

이러한 예외적 병목에 대처하기 위해, OS 단계에서 디스크 파티션 단위 공간이나 .swap 형태의 가상 메모리 크기를 일시적으로 확장(최소 2GB~4GB 규모 이상)할 수 있는 자동화 스크립트 기반 배포 아키텍처(Deployment Architecture)가 임베디드 장비 세팅 과정에 권장된다. 비록 빈번한 스와핑(Swapping)이 I/O 지연을 급증시켜 총 빌드 시간(Makespan)을 대폭 훼손하더라도, 빌드의 무결성 유지 관점에서 OOM 크래시(Crash)에 의한 시스템 리셋 패닉을 회피하기 위한 최종적 안전망(Fail-safe) 체계로서 반드시 기능해야 한다.