BaeBox

Jest memory leak (메모리 누수) 이슈 본문

개발 관련/기타등등 (언어 및 툴 등)

Jest memory leak (메모리 누수) 이슈

배모씨. 2023. 8. 11. 19:02
반응형

Jest

최근에 Nest.js의 테스트 코드를 깃액션에서 돌리다가 터지기 시작했다.
왜그런가하니 Jest의 테스트 코드가 OOM으로 터지고 있었다.
로컬에서도 --logHeapUsage 옵션을 사용해서 찍어보니 메모리 사용량이 엄청 오르는걸 확인할 수 있었다.


수정을 위한 1차 시도. 

isolatedModules 옵션 적용.
각 파일을 개별적으로 컴파일해서 처리하는 옵션인가보다.  (아래 참고 문서 참조)

// package.json
    ...
    "transform": {
      "^.+\\.(t|j)s$": [
        "ts-jest",
        {
          "isolatedModules": true
        }
      ]
    },
    ...

...는 실패.


2차 시도.

--runInBand 옵션 적용. 
로컬에서까지 메모리가 더더욱 미쳐 날뛰기 시작했다. 테스트 케이스 하나당 메모리 사용량이 100mb 씩 오르는 기염을 토하기 시작하는데...

아.. 안 돼!


3차 시도.

node 16.11.0 버전부로 컴파일 캐시가 맛이 갔다는 깃허브 이슈를 보게 됐다. (아래 문서 참조)
나는 18.x.x 버전을 사용하고 있었다.
--no-compilation-cache 옵션 가즈아!

로컬에선 메모리 사용량이 200~300mb 수준으로 비약적으로 떨어졌다!!!
그러나 깃액션에서는 여전히 펑펑 터졌다. 

어... 뭔가?? 원인이 하나가 아니었나??


4차 시도.

1, 3차 시도에서 사용했던 옵션은 괜찮은 옵션이라 유지하고(isolatedModules, no-compilation-cache), 워커 갯수를 고정해서 실행해보았다. 

이 와중에 재밌는 현상을 발견했다.
워커의 갯수가 cpu 쓰레드의 최대갯수에 가까워질 수록 메모리 샤용량이 줄고, 줄어들수록 메모리 사용량이 늘어나는걸 확인했다.

하...


잠정적으로 내린 결론.

아마 제스트의 멀티쓰레딩 과정에서 어딘가 문제가 생긴게 아닌가 싶다. (제스트 팀은 노드팀에 책임을 전가하고 있다. ㅋ)

조심스레 위 3차 시도에서 깃액션에서 터졌던 이유를 유추해보자면, 도커 컨테이너 내부에서 사용할 수 있는 cpu 자원에 제약이 있어서(1개로) 해당 옵션을 가져오게되면 runInBand 옵션이나 마찬가지인 상태로 돌아서 메모리가 뻥뻥 터진게 아니었을까? 아니나 다를까 확인해보니 깃액션이 도는 컨테이너의 기본 설정은 vcpu 1개, max는 4개였다.

현재로서는 완벽한 해결은 어려워서 maxworker 갯수를 n개로 설정해서 테스트 코드가 터지지 않는 수준에서만 설정해서 사용하고 있다.
실제 cpu에서 지원하는 쓰레드의 갯수보다 더 설정해도 문제는 안 생기니 걱정은 안해도 된다. 

 

 

+ 추가 2023.08.12.  더욱이 Jest 측에서도 답이 없었는지 --workerIdleMemoryLimit 이라는 설정을 만들어두었다. (아래 링크 문서 참조)이게 뭔가하면 워커의 메모리 사용량이 설정값 이상 넘어가면 워커를 재실행하는 기능이다. 워커갯수와 이 기능을 잘 조합해서 사용하면 --runInBand 도 속터지지만 사용 가능하다. 

+ 추가2 내가 정착한 옵션. 

...
    "clearMocks": true,
    "workerThreads": true,
    "workerIdleMemoryLimit": "256MB",
    "transform": {
      "^.+\\.(t|j)s$": [
        "ts-jest",
        {
          "isolatedModules": true
        }
      ]
    },
...

https://huafu.github.io/ts-jest/user/config/isolatedModules

 

Isolated Modules option

ts-jest is a TypeScript preprocessor with source map support for Jest that lets you use Jest to test projects written in TypeScript.

huafu.github.io

https://github.com/jestjs/jest/issues/11956

 

[Bug]: Memory consumption issues on Node JS 16.11.0+ · Issue #11956 · jestjs/jest

🚨 Using Jest 29, you can use --workerIdleMemoryLimit. See https://jestjs.io/docs/configuration/#workeridlememorylimit-numberstring 🚨 Version 27.0.6 Steps to reproduce Install the latest Node JS (16...

github.com

https://jestjs.io/docs/configuration#workeridlememorylimit-numberstring

 

Configuring Jest · Jest

The Jest philosophy is to work great by default, but sometimes you just need more configuration power.

jestjs.io

 

반응형
Comments