OS 성능 튜닝에서 CPU·메모리·I/O 병목 다루기
운영체제 성능 튜닝을 위한 CPU 스케줄링, 메모리 누수 탐지, I/O 병목 분석과 모니터링 전략
2026-08-14 · 최초 발행 2026-01-16
자원 사용 패턴을 먼저 분리해야 병목이 보인다
운영체제 성능 튜닝은 시스템 자원을 효율적으로 사용하도록 조정해 성능을 끌어올리는 작업이다. CPU 스케줄링 최적화, 메모리 누수 탐지, I/O 병목 분석은 응답 속도·처리량·안정성에 직접 연결되는 세 축이다. 어느 하나만 조정하기보다, 현재 워크로드가 어느 자원에서 지연되는지부터 구분해야 한다.
CPU 시간을 어떤 작업에 배분할지 결정하기
스케줄링 정책은 워크로드 성격에 맞춰 선택한다. 실시간 시스템에는 SCHED_FIFO, SCHED_RR을 사용하고, 일반 시스템은 CFS(Completely Fair Scheduler)를 사용한다. 배치 작업은 SCHED_BATCH로 처리량 최적화를 고려할 수 있다.
프로세스를 특정 CPU 코어에 고정하는 CPU 친화성(Affinity) 설정도 유용하다. 캐시 히트율을 높이고 컨텍스트 스위칭 비용을 줄일 수 있으며, taskset과 numactl로 제어한다. NUMA 환경에서는 메모리 접근 지역성을 확보하는 데도 관련된다.
우선순위는 Nice 값으로 조정한다. 중요한 프로세스에는 높은 우선순위를 부여하되, 우선순위 역전 문제에는 우선순위 상속 기법을 적용한다.
컨텍스트 스위칭 자체도 관찰 대상이다. 프로세스 수를 제한해 스위칭 빈도를 낮추고, 스레드 풀로 생성과 소멸 비용을 줄일 수 있다. vmstat은 컨텍스트 스위칭을 모니터링할 때 사용한다.
증가하는 메모리 사용량의 원인을 추적하기
메모리 누수는 동적 할당 뒤 해제가 누락될 때만 발생하지 않는다. 순환 참조로 인한 가비지 컬렉션 실패, 파일 디스크립터와 소켓 같은 리소스의 미해제, 제한 없이 늘어나는 캐시 데이터도 원인이 된다.
누수가 의심되면 도구별 역할을 나눠 확인한다. Valgrind는 메모리 할당과 해제를 추적해 누수 지점을 정확히 파악하고, AddressSanitizer는 컴파일 시 삽입되어 빠른 실행 속도를 제공한다. Heaptrack은 힙 메모리 사용 패턴 분석에 사용한다. top, ps 명령어로는 메모리 사용량을 실시간으로 모니터링할 수 있다.
프로파일링에서는 메모리 할당 패턴, 피크 메모리 사용량, 메모리 단편화 정도, 페이지 폴트 빈도를 함께 본다. 예방 측면에서는 RAII(Resource Acquisition Is Initialization) 패턴과 스마트 포인터를 적용하고, 정기적인 메모리 감사 및 자동화된 누수 검사 CI/CD 파이프라인 통합을 고려한다.
I/O 지연이 발생하는 계층 찾기
I/O 상태는 IOPS(Input/Output Operations Per Second), 처리량(Throughput), 응답 시간(Latency), 대기 큐 길이(Queue Depth)로 읽을 수 있다. IOPS는 초당 입출력 작업 수, 처리량은 단위 시간당 전송 데이터량, 응답 시간은 요청부터 응답까지 걸리는 시간, 대기 큐 길이는 대기 중인 I/O 요청 수다.
iostat은 디스크별 I/O 통계를 제공하고, iotop은 프로세스별 I/O 사용량을 실시간으로 표시한다. blktrace는 커널 블록 계층 I/O를 추적하며, sar은 I/O 통계를 포함한 시스템 활동 보고서를 제공한다.
병목 위치에 따라 I/O 스케줄러도 달리 선택한다. CFQ(Completely Fair Queuing)는 공정성을 우선하는 일반 워크로드에, Deadline은 응답 시간 보장이 필요한 데이터베이스 서버에 적합하다. Noop은 오버헤드를 최소화하는 SSD 환경에, BFQ(Budget Fair Queuing)는 대화형 애플리케이션의 응답성 향상에 활용한다.
파일시스템은 noatime, nodiratime 같은 마운트 옵션, 블록 크기, ordered·writeback·journal 저널링 모드, 파일시스템별 특화 옵션을 조정할 수 있다. 페이지 캐시 크기, 디렉토리 엔트리 캐시(dentry cache), Read-ahead 크기, Write-back 정책 역시 함께 검토한다.
측정과 변경을 반복하는 운영 루프
성능 튜닝은 한 번의 설정 변경으로 끝나지 않는다. CPU, 메모리, I/O, 네트워크 메트릭을 수집하고 로그를 집계·분석하며, 성능 베이스라인과 이상 탐지·경보 체계를 마련한다.
성능 테스트는 벤치마크 설계부터 부하 생성, 측정, 결과 분석, 파라미터 조정으로 이어진다. sysbench, fio, stress-ng 같은 도구를 사용하고, 순차·랜덤 및 읽기·쓰기 부하 패턴을 구분한다. 재현 가능한 테스트 환경에서 A/B 테스트로 튜닝 효과를 검증한다.
운영체제 레벨에서는 vm.swappiness, vm.dirty_ratio 등의 sysctl 설정, 네트워크 버퍼 크기, 파일 디스크립터 제한, 세마포어와 공유 메모리 한계를 조정한다. CPU 핫스팟은 perf, 시스템 콜은 strace, 라이브러리 호출은 ltrace, 커널 레벨 트레이싱과 성능 분석은 eBPF로 확인한다.
워크로드별 조정 지점
CPU 집약적 워크로드에서는 CPU 코어 수에 맞춰 워커 프로세스 수를 조정하고, CPU 친화성으로 캐시 효율을 높인다. 하이퍼스레딩 활성화·비활성화 테스트와 NUMA 노드 균형 유지도 점검한다.
메모리 집약적 워크로드에서는 Huge Pages 활성화로 TLB 미스를 줄이고, 스왑 사용을 최소화한다. 메모리 압축 기능 활용과 OOM Killer 정책 조정도 대상이 된다.
I/O 집약적 워크로드는 RAID 구성으로 I/O 부하를 분산하고, SSD 도입으로 랜덤 I/O 성능 향상을 노릴 수 있다. 비동기 I/O와 메모리 맵 파일은 I/O 오버헤드 감소에 활용한다.