개발 공부/서버
[서버 성능 최적화] 메모리 & 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 관리: 반복/무거운 작업은 비동기 처리 또는 워커 분리
- 도구 사용: 실시간 모니터링 + 로그 추적 필수
반응형