윈도우 메모리 누수 대처하기

Development

윈도우는 저에게 있어서 참 애증의 관계입니다. 우선 윈도우는 개발하기에 참 불편한 플랫폼이라고 개인적으로 생각합니다. 우선은 도커(WSL 사용해야 함), 레디스(Memurai 사용해야 함) 등 네이티브하게 지원되지 않는 것들이 많습니다. 그리고 일반적인 경우에는 Posix 와 호환이 되지 않기 때문에 서버와 유사한 환경을 구축하기도 어렵고 타 OS와 달라도 너무 다르다고 생각합니다. 그래서 모든걸 내려놓고 아치리눅스를 메인으로 쓰고자 몇번이나 다짐하긴 했었는데, 게임 등 여러 프로그램으로 인해 어쩔 수 없이 윈도우를 메인으로 사용하고 있습니다.

그럼에도 몇 번씩 인내심의 한계를 느끼는 일이 있는데, 그 중 하나가 메모리 누수였습니다. 작업관리자에서 분명히 사용하는 프로세스는 없는데 제 메모리는 축나있는 일이 많았습니다. 이로 인해 메모리를 24기가까지 증설했음에도 항상 메모리가 가득차는 것을 보고 칼을 빼들어야겠다고 생각했습니다.

풀 사용량 확인

우선 가장 처음으로 한 일은 풀의 사용량을 확인하는 거였습니다.

제 작업관리자 성능 / 메모리 사진인데, 페이징 풀과 비 페이징 풀이 각각 700MB / 941MB 를 차지하고 있습니다. 이 정도면 정상적인 경우입니다만, 혹시라도 풀이 비 정상적으로 높게 차지할 경우에는 Windows Developer Kit에 딸려오는 Poolmon이라는 툴을 이용해서 어떠한 드라이버에서 메모리를 많이 차지하는지 체크해보시면 될 것 같습니다.

B를 눌러 바이트 순으로 정렬하신 후에 앞에 Tag에 해당하는 데이터로 찾으시면 됩니다. [Pool Tag로 드라이버 찾는 법]

좀비 프로세스 체크하기

두 번째로 많은 이유가 있을 수 있겠지만, 다른 하나의 이유는 좀비 프로세스입니다. 리눅스 계열에만 좀비 프로세스가 있는 줄 알았는데 윈도우에도 좀비 프로세스가 있었습니다. 하지만 놀랍게도 윈도우는 모든 API 등에서 좀비 프로세스를 꽁꽁 숨깁니다. 따라서 작업관리자에서도 보이지 않았고, 발견이 늦었던 것 같습니다.
[좀비 프로세스를 찾아서]

문제는 도대체 어떠한 프로세스가 좀비 프로세스를 만드는지, 그리고 어떤 좀비 프로세스를 만드는지를 찾는 것입니다. 우선 제가 사용한 툴은 RamMap이라는 툴인데, 이는 좀비 프로세스 뿐만 아니라 전반적인 메모리 누수를 해결하기에 굉장히 좋은 툴입니다. 마이크로소프트 도큐먼트 또는 SysInternals 공식 홈페이지에서 받으실 수 있습니다.

RamMap을 처음 켜시면 무엇이 얼만큼 사용하고 있는지 직관적으로 확인하실 수 있습니다. 간략한 사용예가 들어있는 마이크로소프트 테크 커뮤니티 글을 남기도록 하겠습니다.

아무튼, Processes 탭에 수 많은 프로세스가 있다면 좀비 프로세스일 가능성이 높은데, 저같은 경우는 conhost.exe, node.exe, git.exe 등이 정말 많이 들어있었습니다. 따라서 처음에는 clink powerline의 버그라고 생각하였지만 결론은 아니었지 않나 싶습니다.

그러던 중 Random ASCII 라는 블로그의 좀비 프로세스 관련 글을 발견하였는데, 해당 글 작성자분께서 제작하신 FindZombieHandles 라는 툴을 사용하여 찾아본 결과, 약 7만개의 핸들이 열려있었습니다.

결론

저 프로세스들이 어째서 좀비 프로세스로 살아있는 지는 모르겠지만, 왜 생기는 지는 알게 되었습니다. 제 컴퓨터에 pm2를 통해서 내부 서버를 운영하고 있었는데, 스크립트에 버그가 있어서 무한히 재시작하느라 node가 계속 실행되는 것이었습니다. 정확한 원인은 모른채로 그냥 그것만 수정하고 나니 메모리 릭이 잡혀서 그대로 살았는데, 최근에 시그윈 도큐먼트를 읽다가 혹시 이건가? 하는 부분은 생겼습니다.

Cygwin FAQ 에 따르면 복잡한 fork() 구현으로 인해서 가끔씩 프로세스 생성에 이슈가 있다고 하는데 알려진 충돌하는 프로세스 목록에는 제가 사용하는 여러 프로그램들 (Avira Antivir, ConEmu, MacType 등)이 있었습니다. 이로 인한 문제들 중에는 메모리릭/핸들릭과 랜덤한 fork() 실패가 있다고 합니다. 후자는 이미 겪고 있기 때문에 전자도 해당되는게 아닐까 현재로서는 추측만 하고 있습니다.