“화면이 종종 멈추는 것 같아요. 아마도 OOM 이슈인 것 같은데 한 번 봐주실 수 있나요?”
OOM은 Out Of Memory의 약자로, 말 그대로 메모리가 한계를 벗어났다는 뜻입니다.
OOM이 발생한 배경을 간략하게 설명하자면,
ECS로 서빙 중인 Next.js 어플리케이션
Task가 종료된 로그가 있었음
Task가 종료된 사유는 아니나 다를까 OOM
✏️ ECS나 Task 같은 용어를 몰라도 아래 글을 읽는데 무방합니다.
Task는 Next.js가 실행되는 환경이고 ECS는 그 Task를 쉽게 관리하는 서비스입니다.
로그를 좀 더 자세히 봤더니 아래와 같은 로그를 발견했습니다.
npm 로그 파일을 볼 수 없는 상황이라 대충 짐작해보자면,
Task에 할당된 메모리는 1GB였고, 어플리케이션이 1GB보다 초과하는 메모리를 사용하여 리눅스의 OOM 킬러에 의해 어플리케이션이 종료된 듯 합니다.
여기서 궁금한 건 어디서 메모리를 그렇게 많이 쓰길래? 입니다.
우선 OOM이 발생해서 어플리케이션이 자꾸 죽으면 곤란하니까 임시방편이 필요했습니다. ChatGPT와 논의한 결과,
Task의 메모리 할당량을 늘려라
Node.js의 메모리 할당량을 늘려라?
node 에도 메모리를 제어할 수 있는지 몰랐습니다 �
— max-old-space-size 옵션을 사용해서 메모리 제한을 늘리라고 하네요.
— max-old-space-size 옵션을 늘린다는 건 어떤 의미일까요?
이름을 그대로 해석해보면 오래된 영역의 최대 크기를 늘린다는 것 같네요.
여기서 말하는 오래된 영역은 힙 메모리 중 오래된 영역을 뜻합니다.
V8 엔진은 힙 메모리 영역을 2가지로 구분하는데요,
New Generation (새로운 세대)
Old Generation (오래된 세대)
New Generation에는 새로 생성된 객체들이 존재하고, 가비지 컬렉터(GC)가 자주 동작합니다. New Generation 영역에서 작동된 GC에서도 살아남은 객체들이 Old Generation으로 이동합니다.
Old Generation에는 생명 주기가 긴 객체들이 존재하고 GC가 비교적 덜 동작합니다. Old Generation 영역이 차게 되면 메모리 차지를 많이 하게 되는거죠.
빨리 먹고 빨리 나가주는 손님은 회전율에 도움 되지만, 몇 시간씩 눌러앉아있는 손님들이 많아지면 가게는 새로운 손님을 받을 수 없게 되는거죠.
그래서 Old Generation, 즉 old space의 영역 크기를 늘리기 = 어플리케이션 메모리 할당량 늘리기인 것 같네요.
Task의 메모리 할당량과 node의 max-old-space-size 도 늘려서 배포 했더니 일단 급한 불은 껐습니다.
❓얼마나 늘려야하나요?
시스템에 총 얼마를 할당해야하는지는 어플리케이션 상황에 따라 달라 정할 수 없지만, max-old-space-size 값은 시스템 메모리 할당량보다 조금 적게 설정해야합니다.
* On a machine with 2 GB of memory, consider setting this to 1536 (1.5 GiB) to leave some memory for other uses and avoid swapping. (https://nodejs.org/api/cli.html#--max-old-space-sizesize-in-mib)
= 메모리가 2GB인 컴퓨터에서는 1.5GB으로 설정하여 일부 메모리를 다른 용도로 남겨두고 스왑을 피하는 것이 좋다고 합니다.
다음에 이런 일이 발생한다면 메모리를 무작정 계속 늘릴 순 없습니다 �
메모리가 어디서 많이 사용되는지 파악하고 근본적인 해결책을 얻고싶습니다.
다음 파트에서는 메모리가 어디서 많이 사용되는지 파악하는 방법에 대해서 적어볼까 합니다.
다음주 월요일에 또 신나게 뜁니다! �