OPEN HYPER STEP
← 목록으로 (stack-analysis)
STACK-ANALYSIS · 97 / 120
stack-analysis
CHAPTER 97 / 120
읽기 약 2
FUNCTION

메모리 관리: 프로파일링 + 누수 탐지


핵심 개념

heap snapshot·closure leak·event listener·React leak — 메모리 폭주 방지.

본문

Node.js 메모리 모니터링

TYPESCRIPT📋 코드 (17줄)
// 주기적 메모리 보고
setInterval(() => {
  const mem = process.memoryUsage();
  console.log({
    rss: `${Math.round(mem.rss / 1024 / 1024)}MB`,        // 전체 RAM
    heapTotal: `${Math.round(mem.heapTotal / 1024 / 1024)}MB`,
    heapUsed: `${Math.round(mem.heapUsed / 1024 / 1024)}MB`,
    external: `${Math.round(mem.external / 1024 / 1024)}MB`,
  });
}, 60000);


// Sentry 자동 전송
import * as Sentry from '@sentry/node';
setInterval(() => {
  Sentry.metrics.gauge('memory.heap_used', process.memoryUsage().heapUsed);
}, 30000);

메모리 누수 패턴 5가지

TYPESCRIPT📋 코드 (48줄)
// 1. 글로벌 변수 누적
const cache = {};  // ❌ 무한 성장

// ✅ 제한된 캐시 (LRU)
import LRU from 'lru-cache';
const cache = new LRU({ max: 1000, ttl: 1000 * 60 * 5 });


// 2. Event Listener 누수
const listener = () => doSomething();
emitter.on('event', listener);
// ❌ 제거 안 함

// ✅
emitter.off('event', listener);


// 3. Closure 누수
function makeHandler() {
  const big = new Array(1000000);  // 큰 객체
  return function() {
    return 'small';  // big 참조 안 하지만 closure에 잡힘
  };
}

// ✅
function makeHandler() {
  return function() {
    return 'small';
  };
}


// 4. setInterval 누수
const interval = setInterval(work, 1000);
// ❌ clearInterval 안 하면 GC 안 됨

// ✅
clearInterval(interval);


// 5. Stream 미닫기
const stream = fs.createReadStream(file);
// ❌ 에러 시 close 안 함

// ✅
stream.on('error', () => stream.destroy());
stream.on('end', () => stream.destroy());

Heap Snapshot (Chrome DevTools)

BASH📋 코드 (16줄)
# Node.js 헤프 덤프
node --inspect server.js
# → chrome://inspect → Memory 탭 → Heap Snapshot


# 또는 v8.writeHeapSnapshot
import v8 from 'v8';
process.on('SIGUSR2', () => {
  const file = `heap-${Date.now()}.heapsnapshot`;
  v8.writeHeapSnapshot(file);
  console.log(`Snapshot: ${file}`);
});


# 트리거
kill -SIGUSR2 <pid>

React 메모리 누수

TSX📋 코드 (38줄)
// ❌ unmount 후 setState
function Component() {
  const [data, setData] = useState();
  useEffect(() => {
    fetch('/api').then(r => r.json()).then(setData);  // unmount 후 호출 가능
  }, []);
}


// ✅ AbortController + cleanup
function Component() {
  const [data, setData] = useState();
  useEffect(() => {
    const controller = new AbortController();
    fetch('/api', { signal: controller.signal })
      .then(r => r.json())
      .then(setData)
      .catch(err => {
        if (err.name === 'AbortError') return;
        // ...
      });
    return () => controller.abort();
  }, []);
}


// ❌ subscription 누수
useEffect(() => {
  socket.on('event', handler);
  // cleanup 누락
}, []);


// ✅
useEffect(() => {
  socket.on('event', handler);
  return () => { socket.off('event', handler); };
}, []);

Stream 메모리

TYPESCRIPT📋 코드 (26줄)
// ❌ 큰 파일 전체 로드
import fs from 'fs/promises';
const content = await fs.readFile('big.csv');  // 1GB → 1GB 메모리


// ✅ Stream
import { createReadStream } from 'fs';
import { parse } from 'csv-parse';

const parser = createReadStream('big.csv').pipe(parse({ columns: true }));

for await (const row of parser) {
  await processRow(row);  // 한 줄씩
}
// → 메모리 KB 수준


// ❌ JSON.stringify 큰 배열
const json = JSON.stringify(millionItems);  // OOM


// ✅ JSONStream
import JSONStream from 'JSONStream';
const stream = JSONStream.stringify('[\n', ',\n', '\n]');
items.forEach(item => stream.write(item));
stream.end();

메모리 한계 + Restart

JAVASCRIPT📋 코드 (20줄)
// PM2 설정 — max_memory_restart
module.exports = {
  apps: [{
    name: 'api',
    script: 'server.js',
    instances: 4,
    max_memory_restart: '500M',  // 500MB 초과 시 재시작
  }],
};


// Kubernetes
resources:
  limits:
    memory: 512Mi
  requests:
    memory: 256Mi


// → OOM 방지 + 자동 복구

clinic.js (Node.js 프로파일러)

BASH📋 코드 (8줄)
pnpm dlx clinic doctor -- node server.js
# → 부하 줘서 진단

pnpm dlx clinic heap-profile -- node server.js
# → 메모리 분석

pnpm dlx clinic flame -- node server.js
# → CPU 핫스팟

다음 챕터

CH.98 "네트워크 최적화: HTTP/3 + 압축 + prefetch".


AI 프롬프트
🤖 AI에게 잘 물어보는 법 — 모델·전략별 프롬프트
Claude

무료: Sonnet 4.6 / Pro $20/mo: Opus 4.6

내 코드의 메모리 관리 부분을 분석해서
실전 분석 + 개선 우선순위를 알려줘.
ChatGPT

무료: GPT-5.5 / Plus $20/mo: GPT-5.5 Pro

메모리 관리 관련 베스트 프랙티스 5가지를
비교 분석해서 패턴 추출를 알려줘.
Gemini

무료: 2.5 Flash / Pro $19.99/mo: 3.1 Pro

내 프로젝트 전체에서 메모리 관리
최적화 가능 위치를 보고해줘.
Grok

무료: Grok 4.1 / SuperGrok $30/mo

2026년 한국 시장의 메모리 관리
트렌드를 솔직히 알려줘.

⭐ 이것만 기억하세요
메모리 관리: 프로파일링 + 누수 탐지 이 3가지만 확실히 잡으세요
1.Node.js 메모리는 RSS·Heap 모니터링 + PM2 max_memory_restart
2.React useEffect cleanup으로 listener·subscription 정리
3.Stream 처리로 큰 파일·데이터 OOM 방지


공유하기
진행도 97 / 120