JavaScript heap out of memory

도도묵·2023년 8월 11일
0

회사에서 기존 프로젝트에 신규 리소스들을 대량으로 추가하는 작업을 진행했는데, 규모가 너무 커져버린 나머지 프로젝트의 서버를 구동하는 과정에서 에러가 발생했다.

<--- JS stacktrace --->

FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory
있는 그대로 해석하면 사용 가능한 heap 메모리가 부족해 주소값을 할당하지 못한다는 말인데.. 구체적인 상황 파악은 안되는것 같다, 좀 더 찾아보자.

📌 힙 메모리 크기 변경하기

Memory Heap(메모리 힙) 란 ?

메모리 할당이 일어나는 곳. 참조 타입(객체 등) 데이터가 저장된다.
즉 실행하는 파일에서 요구하는 메모리의 용량이 너무 크거나 어딘가에서 메모리 누수가 일어나고 있을수 있다는 것. 때문에 더 큰 메모리를 할당해야 하는 상황이다.



⭐️현재 사용 중인 힙의 크기 확인

구글의 크롬 브라우저는 v8엔진을 사용하여 컴파일을 진행하는데 Nodejs 역시 런타임시 v8 엔진을 활용한다. 때문에 v8 소스에 접근해 현재 사용 중인 리소스들에 대한 구체적인 값을 제공 받을수 있는데, 이 중 heap 관련 정보를 제공해주는 메소드가 바로 getHeapStatistics다.



v8.getHeapStatistics()

참조: getHeapStatistics에 대한 설명 문서



제공 받은 object의 heap_size_limit으로 현재 노드에 할당된 힙 메모리를 알 수 있고, 이 값을 다시 1024 제곱으로 나누면 현재 바이트의 크기를 알 수 있습니다.(1024를 제곱으로 나누는 이유는 heap_size_limit이 기가바이트(GB)를 기준으로 하기 때문(1기가바이트(GigaByte) = 1024메가바이트(MegaByte)^2 = 1키로바이트(KiloByte)^4 = 1024바이트^4))

대략 4기가 정도의 힙 메모리를 사용하고 있음을 알 수 있다.



이슈를 해결하고자 용량을 늘리고자 한다면 커멘드 창에

export NODE_OPTIONS=--max_old_space_size="원하는 메모리 사이즈"

를 입력하면 된다.
이를 통해 다시 heap_size_limit을 확인해보면 메모리가 정상적으로 변경된걸 알 수 있다.

8기가로 힙 메모리가 변경된 모습



그러나 이 방법으로 진행하게 되면 매번 실행할때마다 해당 커멘드를 입력해야 된다는 귀찮음이 있다. 해당 커멘드는 현재 터미널이 종료되기 전까지만 유효하기 때문이다. 만약 매번 입력하지 않고도 해당 환경 조건을 영구적으로 유지하고 싶다면 환경 변수를 사용해 전역으로 적용되도록 해야 한다.

📌 환경 변수로 메모리 변경하기


🎈 Window 환경일 때 :

java를 처음 실행할때 jdk 경로를 가져오도록 환경변수에 넣어두듯 노드 옵션도 마찬가지로 넣어두면 된다.

[Windows 설정] - [시스템] - [정보] - [고급 시스템 설정] - [고급] - [환경 변수] - [시스템 변수/사용자 변수]

새로 만들기를 클릭해 변수에 NODE_OPTIONS를, 값에 "max_old_space_size="메모리 크기" 를 넣어두면 된다.(⭐️ 환경 변수는 시스템을 다시 시작해야 적용된다.)

🎈 MAC 또는 Linux 환경일 때 :

MAC과 Linux를 같이 묶어둔 이유는 MAC은 Window 처럼 시스템 변수 적용에 대한 인터페이스가 따로 제공되지 않아 Linux 커멘드를 이용한 접근이 필요하기 때문이다.
1. 우선 bash_profile에 접근해야 한다. 이 파일은 우리가 linux 환경에서 시스템의 환경변수에 접근할 수 있도록 도와줄 것이다.

cd ~/
또는
Command + O

로 현재 시스템의 홈으로 이동한다.
2. 만약 .bashprofile 파일이 이미 존재한다면 open -a TextEdit.app ~/.bash_profile 를 입력해 파일을 연다. ( 해당 파일이 존재하지 않는다면 touch .bashprofile 로 파일을 생성한 뒤 위 과정을 거쳐 파일을 열면 된다.)

.bash_profile 파일이 존재할 경우
open -a TextEdit.app ~/.bash_profile

존재하지 않는 경우
touch .bash_profile

(⭐️참고로 vi ~/.bash_profile을 입력하면 빔으로도 해당 파일을 수정할 수 있다!😎😎😎)
3. 파일을 열었으면 이제 환경 변수 값을 제공하면 된다.
export NODE_OPTIONS="--max-old-space-size='메모리 크기'" 를 입력 한다.
4. 위 작업이 끝나면 시스템을 재시작하거나 source ~/.bash-profile 을 통해 해당 파일을 초기화한다. getHeapStatistics()로 접근해보면 환경 변수에 넣어둔 값이 어떤 경로에서든 똑같이 적용된 걸 확인 할 수 있다.
https://stackoverflow.com/questions/32463212/how-to-set-environment-variables-from-windows
profile
나만의 성장 일기

1개의 댓글

comment-user-thumbnail
2023년 8월 11일

많은 도움이 되었습니다, 감사합니다.

답글 달기