Backend 언어/JS&TS

Jest 'JavaScript heap out of memory'에서 시작된 리팩토링 - (1)

민초부 2021. 4. 30. 14:33
반응형
  • 엄청 간헐적으로 'JavaScript heap out of memory'이라고 말하며 test가 죽어버리는 일이 발생하기 시작 
    > 간헐적으로 발생하고 다른 개발자분들도 동일하게 발생. 다시 돌리면 사라짐 
  • 메모리 누수 때문인거 같아서 시작하였다.
     + 기존 전체 커버리지 테스트 (Service단의 전체 테스트)를 돌리면 너어어어어어무 오래 걸리는게 항상 걸렸다. 
  • 평균 테스트 커버리지는 80% 내외로 총 테스트 갯수는 900정도 됨 
    > 최근 토스 세션에서 말하길 해당 개발자는 약 1400개의 테스트가 걸리고 1분이 넘어가서 리팩토링을 시작하였다고 하였다.
     즉 우린 무조건 손을 봐야하는 수준인거 (4/30일 기준 914개 2분 35초)
  • 이렇게 오래걸리는 이유와 상당한 연관이 있어보였음.
    > 누군가가 테스트를 무한정으로 돌려 Heap out of memory를 발생시키는걸 보아 상관이 있어보인다. 

 

 

  • 원인 후보
    • import를 'import * as '~~~' import Aaa' 와 같이 다 끌어와서 문제인 경우도 있다곤 하는데 영향이 있을 것 같긴한데 이게 크리티컬하게 영향을 줬을 것이라고 생각하진 않는다.
      > 최근 클린코드 책에서도 클린코드를 위해 그냥 전체 import를 해란말이 있었는데 이렇게 크리티컬한 버그를 발생시킬 정도면 권장하지도 않았을 듯
    • Mocking 해주고 다시 Unmocking을 해줘야한다는 얘기도 있음 
      > 이게 메인 원인인거 같다. 뜯어보니 unmocking을 해주는 테스트가 있고 그냥 안 해주고 넘겨버리는 test가 있었다. 
      > 이게 이상해서 전체 테스트를 돌릴 때 개별 테스트가 끝나면 해당 모킹 파일을 클리어해주는 option을 jest.config.js에 넣어줬더니 귀신같이 Fail이 떨어지는 테스트들이 발생했다.  
          (module.export에 clearMocks: true 추가함)
    • 추가로 jest test를 돌리는데 --coverage를 빼고 --logHeapUsage 옵션을 넣어 돌렸더니 또다시 이번엔 다른 곳에서 또 에러가 난다. 일단 이거 수정하고 다시 돌리며 메모리를 어디서 잡아먹는지 보아야 게따 
      --> logHeapUsage때문이 아니라 clearMocks 때문이였음 ㅡㅡ 
      >> 에러 원인 : mock처리 하고 해당 mock object를 몇번 호출했는지 count처리해주는 테스트가 있었는데 과거에 이런 mock clear를 제대로 해주지 않아 그냥 계속 횟수가 초기화 되지 않고 +1 씩 증가시켜서 검사하고 있었음
    • 문제로 삼으니 보인다 coverage 테스트 돌리면 무수한 줄 중간에
      (node:6752) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 message listeners added to [EventEmitter]. Use emitter.setMaxListeners() to increase limit
      라고 간헐적으로 뜬다. 얘는 이미 문제라고 외치고 있었음

 

  • jest option에 clearMocks를 넣어주니 전체 테스트 커버리지 결과 (914개 1분 45초)
    > 속도는 확실히 빨라졌으나 여전히 MaxListenersExceededWarning 경고는 뜨면서 메모리 누수 얘기는 나옴
    > 다른 이유가 또 존재한다.

 

>> 결국 JEST 자체가 메모리 누수에 대해 따로 조치를 하지 않으면 이런 문제가 발생할 수 밖에 없는 것 같다.

    --logHeapUsage 를 통해 테스트를 돌려보면 memory는 계속 쌓이고 있고 특정 문제될 테스트 파일들이 많이 쌓을뿐 계속 쌓인다. 즉 지금 괜찮다고 둬봤자 언젠가는 터질 문제 

 

 

>> 오늘자 업데이트 : http request 쪽 설정을 따로 해줘야하는 문제로 보인다. 일단 지금 서버 분리작업하면서 express에서 nest로 바꾸고 있는데 이 작업 해보고 마저 리팩토링진행할듯 

 

 

반응형

'Backend 언어 > JS&TS' 카테고리의 다른 글

2021 ECMAScript (ES12) 신규 변경점  (0) 2021.09.09
[aws-sdk] aws sdk 3이 나왔다.  (0) 2021.05.14
[nestjs] nestjs를 시작하며  (0) 2021.05.14
[jest] expect를 정리해보자  (0) 2021.04.24
[jest] mocking 사용하기  (1) 2021.04.24