← 아티클 목록

리눅스 CPU 사용률 높음 — 100% 프로세스 추적법 (top·pidstat)

2027-01-18#linux#트러블슈팅#성능

CPU 사용률이 치솟아 응답이 느려질 때, "서버가 느리다"로 끝내지 말고 누가 CPU를 먹는지부터 숫자로 잡습니다. 범인은 보통 하나의 프로세스거나, 한 프로세스 안의 특정 스레드입니다.

1단계 — 전체 그림 (top)

로컬 터미널
top

먼저 상단 부하 평균과 CPU 라인을 봅니다. 1을 누르면 코어별 사용률이 펼쳐집니다.

OUTPUT
%Cpu(s): 82.0 us,  9.3 sy,  0.0 ni,  3.2 id,  5.5 wa

여기서 us(user)가 높으면 애플리케이션 연산, sy(system)가 높으면 커널/시스템콜, wa(iowait)가 높으면 사실 CPU가 아니라 디스크 대기입니다. wa가 높은데 CPU 탓을 하면 엉뚱한 곳을 고치게 됩니다.

2단계 — 어느 프로세스인가 (top 정렬)

top 화면에서 P를 누르면 CPU 사용률 순으로 정렬됩니다. %CPU 상위의 PID를 기억합니다. 한 줄로 뽑으려면:

로컬 터미널
ps -eo pid,ppid,%cpu,%mem,comm --sort=-%cpu | head

3단계 — 어느 스레드인가 (pidstat)

프로세스 단위로는 멀티스레드 앱(JVM 등)의 범인을 못 가립니다. pidstat로 스레드별로 내려갑니다.

로컬 터미널
pidstat -t -p <PID> 1 5

1초 간격, 5회로 스레드별 %CPU를 찍습니다. CPU를 독식하는 TID가 보이면, 그 TID를 16진수로 바꿔(printf '%x' <TID>) 스택 덤프(자바라면 jstack)에서 해당 nid를 찾아 어느 코드인지 짚습니다.

원인별 해결

  1. 무한 루프/스핀: 특정 스레드만 100%, iowait 낮음 → 코드의 busy-wait, 잘못된 재시도 루프 점검
  2. iowait 높음(wa): CPU가 아니라 디스크 병목 → iostat -x 1%util 확인
  3. 컨텍스트 스위칭 폭증: vmstat 1cs 컬럼이 비정상 → 스레드 과다 생성 의심
  4. 특정 시점만 튐: 상시 모니터링이 아니면 못 잡음 → pidstat 또는 perf top을 부하 시점에 실행

체크리스트

로컬 터미널
top                                  # us/sy/wa 구분, 1로 코어별
ps -eo pid,%cpu,comm --sort=-%cpu | head   # 상위 프로세스
pidstat -t -p <PID> 1 5              # 스레드별 CPU
iostat -x 1                          # iowait 의심 시 디스크 확인
vmstat 1                             # 컨텍스트 스위칭(cs) 점검

top·pidstat로 CPU 병목을 직접 끊어보고 user/sys/iowait를 읽어내는 실습은 리눅스 트랙에서 회원가입 없이 무료로 할 수 있습니다.