Next.js 메모리 누수 해결: FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory

리린·2021년 10월 1일
3

Next.js

목록 보기
5/17

사건의 발단

  • 그저 평범하게 Next.js를 사용하여 UI를 만들고 있었다. 백엔드에서 무언가를 가져오는 일 없이, 그저 단순한!!! 퍼블리싱에 가까운 프론트엔드 개발을 하고 있었다는 뜻이다.

  • 컴포넌트 퍼블리싱을 마치고 흡족하게 localhost:3000을 실행시켰다.
    그런데 다음과 같은 무시무시한 에러가 떴다.

    FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory

  • ...? 뭐라고요? 아니 이럴 리가 있나.

사건의 전개

  • 처음에는 고전적인 솔루션. 껐다 켜기를 실행했다. 당연히 안 됐다.
  • 로컬호스트를 괜히 켜봤다. 블로그를 참고하여 cmd 에서 netstat -ano 라는 명령어를 치면 로컬호스트의 상태가 나온대서 쳐봤다. 로컬호스트는 너무나 멀쩡했다.
  • 이제 조금 심각해졌다. 컴퓨터에 문제가 있나?? 별별 생각을 해봤다. 그래서 노트북으로 똑같은 파일을 실행해 봤다. 똑같이 안 되었다. 즉, 컴퓨터의 문제는 아니었다. 포맷은 안 해도 된다는 생각에 일단 한숨을 돌렸다.
  • 에러 메시지를 본격적으로 크롬에 쳐보기 시작했다. 한국어 정보는 커녕 영어로도 정보가 잘 나오지 않았다. 그러던 중 내가 겪는 문제와 가장 비슷한 노드js 메모리 누수 포스팅를 찾았다. 요컨대 1) 메모리 작업을 늘리던지 2) 디버깅을 해서 누수 원인을 알아내든지 둘 중 하나를 택하라는 것이었다.

사건의 절정

  • 디버깅따위 한 번도 해본 적 없다(오열). 아니 언젠가는 하게 되겠지..라고 생각했지만 이렇게 하게 될 줄은 몰랐다 ㅠㅠ
  • 심지어 Next.js에서 디버깅하기 어려웠다.(여기서 또 몇시간 소모) 공식사이트에서 하라는 대로 했는데 안되서 검색 결과 다음과 같이 스크립트를 바꿨다.
"scripts": {
    "dev": "cross-env NODE_OPTIONS='--inspect' next dev",
    "build": "next build",
    "start": "next start",
    "lint": "next lint"
  },
  • dotenv 패키지는 미리 깔아둬야 한다.
  • 이후 npm run dev 를 실행시킨 뒤 chrome://inspect에 접속하여 크롬 디버거를 켠다. 이 부분은 다른 분께서 잘 설명해 두셨으니 크롬에서 디버깅하는 법을 참고하면 된다.
  • 우선 localhost를 실행시켜 봤다.

  • 600메가도 많은데 2기가..? 아니 실화냐. 뭔가 문제가 있는 게 느껴졌다.
  • 자세한 디버깅을 위해 어떤 라이브러리/메서드에 문제가 있는지 확인해보았다.
  • 뭔가 react-dom과 jsx에 문제가 있는 것 같았다. 타입스크립트의 문제인가? 라며 또 삽질을 했다. 그럴 리가 없지. 헤매다가 엉겁결에 vsc코드에서도 문제를 확인했다. 어쨌든 스타일드 컴포넌트 렌더링 쪽에 문제가 있는 게 확실해 보였다.(여기서 또 왕창 삽질)

    그리고 드디어 원인을 찾았다!!

사건의 결말

  • 드디어 원인을 찾아냈다. index.tsx의 Home()함수 안에 다른 곳에서 선언한 Home()이라는 컴포넌트를 가져온 것이다.

  • 그러니 상호 참조가 되어 지독하게 얽히고 설키다가 메모리가 펑 하고 터진 것이다.
    아니 애초에 프론트에서 서버가 터질 일이 뭐가 있겠냐고... (나쁜말나쁜말)

  • 결국 컴포넌트 함수명을 Greet으로 바뀌었더니 너무나 쉽게 해결되었다.

회고

  • 에러는 확실히 개발자를 성장시키는 것 같다. 노력한 것에 비해 정말 어이없이 해결되었지만, 그 과정에서 디버깅하는 법이라던지, 로컬호스트 네트워크 확인하는 법, 에러 메시지 확인하는 법(타입스크립트를 지원하는 vscode는 생각보다 많은 것을 알고 있다!) 등 많은 것을 배울 수 있었다. 한국어 자료가 전무하다 보니 심지어 영어 실력도 조금 늘었다(...)

  • 사실 너무 황당해서 기록은 커녕 생각하고 싶지도 않았지만.. 혹시나 똑같이 골머리를 앓을 미래의 개발자를 위하여 기록을 남겨둔다. 이미 해결한 에러라서 그런가, 기록하다보니 좀 재밌는 경험이었던 것 같다.

profile
개발자지망생

3개의 댓글

comment-user-thumbnail
2022년 6월 27일

같은 상황이었는데 덕분에 해결했습니다. 정말 감사합니다ㅠㅠ 행복하세요

답글 달기
comment-user-thumbnail
2022년 11월 15일

매우 좋은 경험을 공유해주신 것 같네요.. 멋지십니다. 감사합니다!

답글 달기
comment-user-thumbnail
2023년 11월 29일

node.js 가장 최근 버전의 LTS로 업 하세요. dotenv를 설치할 필요 없습니다. (node.js에 내장됨)
(TMI: fetch도 포함되어 따로 fetch를 설치하거나 axios를 설치해서 쓰지 않아도 됨)

답글 달기