개발 공부/서버

[서버 성능 최적화] 메모리 & CPU 최적화, GC 튜닝과 메모리 누수 잡기

악마의 개발자 2025. 5. 29. 20:00
반응형

서버 성능 최적화


💡 “서버가 점점 느려지는데… 재시작하면 빨라져요?”

이런 경험 있으셨나요?

“처음엔 잘 돌아가다가 시간이 지날수록 느려져요.”
“CPU 사용률이 90%까지 올라가요.”
“메모리 점유율이 계속 쌓이더니 터졌어요.”

→ 이런 현상은 대부분 메모리 누수(memory leak) 또는 GC 설정 미비 때문입니다.


🧠 메모리 누수란?

사용한 메모리를 해제하지 않고 계속 쌓아두는 현상

  • JS, Java, Python 등 대부분의 언어는 GC(Garbage Collector)가 메모리를 자동 관리하지만,
  • 참조가 끊기지 않은 객체GC의 대상이 되지 않음
    → 결국 메모리 점유율이 계속 상승하다가 서버가 다운됩니다.

✅ 자주 발생하는 누수 예시 (Node.js)

let cache = {};
function saveData(key, value) {
  cache[key] = value; // 너무 많은 데이터를 여기에 계속 저장!
}

✅ 해결: LRU 캐시, TTL, 최대 용량 제한 등 메모리 관리 로직 필요


🔧 메모리 최적화 전략

전략 설명
참조 해제 사용 끝난 객체는 null 또는 삭제
LRU 캐시 적용 오래된 데이터 자동 제거 (Least Recently Used)
메모리 제한 설정 Node.js: --max-old-space-size=512
중복 데이터 제거 동일 데이터 여러 곳에 저장하지 않기
외부 캐시 사용 Redis 등 외부 저장소로 메모리 분산
 

🧰 GC(Garbage Collection) 튜닝

✅ Node.js (V8 기반)

  • 기본 메모리 제한: 약 1.5GB
  • 설정 방법:
node --max-old-space-size=1024 app.js

→ 메모리 한계를 높여 Out of Memory(OOM) 방지

 

✅ Java (JVM 기반)

옵션 설명
-Xms 초기 메모리 크기
-Xmx 최대 메모리 크기
-XX:+UseG1GC 최신 GC 방식 (G1GC, ZGC 등)
 

✅ GC 로그를 통해 Full GC 빈도 확인 → 과도하면 튜닝 필요


🔍 CPU 사용률 최적화

문제 원인 해결 방법
무한 루프 루프 조건 재확인, 종료 조건 명확히 설정
무거운 동기 연산 워커 스레드 또는 큐로 분리
API 반복 호출 중복 요청 방지 로직 구현
이미지/파일 변환 별도 서버 또는 워커 프로세스로 분산 처리
 

📈 실무에서 메모리/CPU 모니터링 도구

도구 용도
top / htop 실시간 리소스 확인
pm2 monit Node.js 앱 상태 시각화
New Relic / Datadog / Grafana APM 도구로 메모리/CPU 추적
Heap Snapshot 메모리 사용 객체 분석 (DevTools, Chrome)
 

🧠 정리 한마디!

"서버는 느려지기 전에 신호를 보냅니다.
메모리와 CPU를 먼저 의심하고, 숫자로 확인하세요."

 

✔️ 핵심 요약:

  • 메모리 누수 방지: 참조 해제 + 캐시 관리 + 외부 저장소 활용
  • GC 튜닝: 런타임 메모리 설정 + Full GC 방지
  • CPU 관리: 반복/무거운 작업은 비동기 처리 또는 워커 분리
  • 도구 사용: 실시간 모니터링 + 로그 추적 필수
반응형