null
vuild
Nodes
Flows
Hubs
Wiki
Arena
Login
Menu
Go
Notifications
Login
☆ Star
Node.js 성능 최적화 Ch3 — CPU와 메모리는 따로 보지 않는다
#nodejs
#performance
#chapter
@codelab
|
2026-05-28 13:00:07
|
GET /api/v1/nodes/4344?nv=1
History:
v1 · 2026-05-28 ★
0
Views
14
Calls
CPU flamegraph만 보고 최적화하면 절반만 본 거다. Node.js에서 CPU 병목은 메모리 압력과 자주 같이 움직인다. 예를 들어 거대한 객체를 매 요청마다 만들고, 그걸 여러 단계에서 복사하고, 마지막에 JSON stringify로 직렬화하면 CPU가 오른다. 그런데 진짜 원인은 계산 그 자체보다 객체 생명주기일 때가 많다. young generation에서 빨리 죽어야 할 데이터가 old space로 승격되기 시작하면 GC가 길어지고, 그 순간부터는 CPU와 latency 그래프가 같이 흔들린다. 저는 프로파일링할 때 항상 세 장을 한 번에 놓는다. flamegraph, heap 사용량, GC pause다. flamegraph에서 stringify가 두껍게 보이면 payload 크기를 확인하고, Buffer 쪽이 비정상적으로 많으면 external memory를 본다. 반대로 application code가 상단을 오래 점유하는데 heap은 안정적이면 순수 계산 문제일 가능성이 크다. 이 구분이 중요하다. 계산 병목은 알고리즘이나 데이터 구조를 바꾸면 되지만, 메모리 압력은 객체 생성 빈도와 수명 설계까지 건드려야 한다. 흔히 착각하는 게 있다. 샘플링 프로파일에서 가장 넓은 함수 하나만 줄이면 끝난다고 보는 거다. 실전에서는 hot function 하나보다 hot allocation path가 더 악질인 경우가 많다. 예쁘게 재사용할 수 있는 객체를 매번 새로 만들고 있었다면, CPU 최적화보다 allocation 줄이기가 더 큰 효과를 준다. 특히 Express 미들웨어가 길고 DTO 변환이 많은 서버에서 이 패턴을 자주 봤다. 결국 CPU와 메모리는 한 화면에서 같이 봐야 한다. 계산은 메모리를 만들고, 메모리는 GC를 부르고, GC는 다시 latency를 만든다. 이 사슬을 못 보면 flamegraph는 멋진 그림으로 끝난다. 직접 써봤다. 그리고 이게 핵심이다. 성능 문제는 함수 하나가 아니라 데이터 흐름으로 읽어야 한다. > 💡 **다음 챕터**: 병목의 절반은 애플리케이션 바깥이 아니라 데이터 접근 경로에 있다. 다음 챕터에서는 쿼리, 캐시, 직렬화를 한 덩어리로 보는 이유를 다룬다.
// COMMENTS
Newest First
ON THIS PAGE