brunch

node.js의 OOM — 범인을 찾아서 Part.2

by 글러닝


Part 1에서는 nodejs의 — max-old-space-size 옵션에 대해 알아봤습니다.
— max-old-space-size 값을 증가시키면 어플리케이션의 힙 메모리 크기가 늘어나 OOM을 어느 정도 해결할 수 있었습니다.


하지만 인프라 리소스에는 한계가 있고 메모리를 계속해서 늘릴 수는 없겠죠. 어느 부분에서 메모리를 많이 잡아먹길래 OOM까지 발생하는지 찾아봐야겠습니다.


1. 테스트 환경 만들기


프로덕션 환경에서는 여러 사용자가 동시에 리소스를 사용하면서 OOM이 발생할 텐데요, 디버깅하자고 프로덕션 환경에 계속 OOM이 발생하도록 놔둘 수도 없는 노릇입니다.


그래서 Part 1에서 소개한 — max-old-space-size를 조정해서 로컬에서 OOM을 재현해 봤습니다.


저는 Nextjs를 사용 중이라 아래와 같이 package.json 파일의 scripts 명령어를 수정했습니다.

//package.json 파일 중
"scripts": {
"dev": "NODE_OPTIONS=\"--max-old-space-size=256\" next dev",
"build": "next build",
"start": "NODE_OPTIONS=\"--max-old-space-size=128\" next start",
},


위와 같이 — max-old-space-size을 조정하고 로컬 서버를 띄워서 어플리케이션을 이리저리 사용해 봤습니다.

←- JS stacktrace - ->
FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memory

개발 모드로 어플리케이션을 실행하면 위와 같은 에러 메시지가 콘솔에 기록되면서 어플리케이션이 죽습니다.

프로덕션 모드로 어플리케이션을 실행하면 어느 정도 동작하다가 메모리가 부족하다는 로그와 함께 서버가 재시작됩니다.


실제로 리눅스에서 주는 OOM 킬러 시그널에 의해서 어플리케이션이 죽는 과정은 약간 다르지만, 위 과정을 통해서 OOM이 발생하는 대략적인 위치를 짐작할 수 있었습니다.


이건 제 개인적인 케이스이지만, 문제가 있는 페이지라고 짐작했던 곳의 이전 페이지에서 메모리 누수가 발생하고 있는 듯했습니다.


이제 제 짐작에 좀 더 확신을 줄 수 있는 데이터가 필요합니다.


2. nodejs의 — inspect 옵션


— inspect 옵션을 사용하면 nodejs를 디버깅할 수 있는데요, 여러 가지를 디버깅할 수 있지만 메모리 디버깅 방법을 중심으로 살펴보겠습니다.


위에서 수정했던 scripts 명령어에 — inspect 옵션을 추가했습니다.

//package.json 파일 중
"scripts": {
"dev": "NODE_OPTIONS=\"--max-old-space-size=256 --inspect\" next dev",
"build": "next build",
"start": "NODE_OPTIONS=\"--max-old-space-size=128 --inspect\" next start"
},


— inspect 옵션을 켜고 서버를 실행하면 브라우저 개발자 창에 nodejs 아이콘이 보입니다.


1*qA7nchJIgoowDgfmuWTOow.png nodejs 아이콘 표시
1*SZnW2sTMEo2BOSXYKtNCrQ.png

nodejs 아이콘을 누르면 위와 같은 창이 보입니다. 1️⃣메모리 탭을 선택하고 2️⃣녹화 버튼을 누르면 메모리 사용 현황이 아래와 같이 기록됩니다.


1*w_nprOwmn2Mpf7YGoBKNeQ.png

회색 그래프는 할당되었다가 해제된 메모리 영역, 파란색은 할당된 후 계속 유지되는 메모리 영역입니다.

그래프에서 파란색 막대가 많아지면 메모리 영역을 계속 잡아먹고 있다는 뜻입니다!


파란색 영역이 쌓이는 부분을 클릭해서 코드 스택을 보면 어느 정도 유추할 수 있을 것 같습니다.


메모리 누수가 발생하는 곳의 위치는 대략적으로 파악했는데 정확히 여기다! 하는 곳은 아직 찾지 못했네요 � 다음 파트에서 좀 더 자세히 디버깅해보는 내용을 써보려고 합니다.


다음 주 월요일에 계속 뜁니다!



keyword
매거진의 이전글node.js의 OOM — 범인을 찾아서 Part.1