제 프로젝트는 사용자가 특정 차트를 고르면, 코스피 코스닥 전 종목의 과거(10년) 차트들을 모두 탐색하여 가장 유사한 차트 10개 정도를 골라 사용자에게 보여주는 것이 목표입니다.
비슷한 차트 검색기
전 종목의 최근 10년간 모든 차트를 탐색합니다. 내 종목의 차트는 과연 상승하는 차트일까요?
www.similarchart.com
파이썬 알아서 메모리관리 해준다며..
파이썬 메모리 주의할 점
파이썬과 자바는 C와 달리 free()
로 메모리 해제를 하지 않아도 자동으로 가비지컬렉터가 메모리해제를 해준다고 알고 있습니다.
하지만 함수가 길어지거나 불필요한 변수들을 신경 쓰지 않고 있으면 자신도 모르는 사이 불필요한 메모리가 계속 쌓이는 경우가 있습니다.
특히 제가 깨닫고 당황했던 부분은 코드블록 안에 선언된 변수가 해당 코드블록 영역을 벗어나도 해제되지 않고 계속 유지가 된다는 부분입니다.
for i in range(10):
a = 1
print(a)
위와 같이 코드를 구성하였을 경우 C계열 언어나 자바는 a를 인식하지 못하는 것으로 알고 있습니다. 그런데 파이썬은 a가 계속 유지된다는 점이 제 허를 찔렀습니다.
이때 함수가 길어지는 경우, 자신도 모르게 메모리를 많이 차지하는 필요 없는 변수들이 쌓이더군요. 그래서
del a
gc.collect()
곳곳에 위와 같이 사용하지 않는 변수들을 del로 해제해 주고 혹시 몰라서 가비지컬렉터를 직접 실행해 주었습니다.
제일 저렴한 AWS 프리티어 서버를 사용하다 보니 메모리 때문에 자꾸 서버가 멈추더군요.. 메모리관리에 신경을 많이 쓰는 중입니다.
matplotlib 메모리누수
파이썬에서는 matplotlib 라이브러리로 여러 그래프나 이미지들을 만들 수 있습니다.
import matplotlib.pyplot as plt
for i in range(100):
fig = plt.figure(figsize=(7, 5))
그런데 위와 같이 반복해서 여러 번 그래프를 그리다 보면 메모리가 plt에 계속 쌓이는 문제가 있습니다.
import matplotlib.pyplot as plt
for i in range(100):
fig = plt.figure(figsize=(7, 5))
plt.clf() # figure 창 내의 plot을 지우는 방법
plt.close('all') # figure 창 자체를 지우는 방법
이를 해결하기 위해서는 plt.clf()
또는 plt.close('all')
함수를 사용해 메모리를 해제할 수 있습니다. 하지만..
matplotlib + flask 메모리누수 문제
제 프로젝트에는 flask로 사용자에게 요청을 받으면 matplotlib로 이미지를 그린 후 사용자에게 응답하는 부분이 있습니다. 이미지를 그린 후 위와 같이 plt.clf()와
plt.close('all')
함수를 사용해 메모리 해제를 해줍니다. 하지만, 동시에 수많은 요청이 들어오는 경우 문제가 발생합니다.
요청버튼을 매우 빠르게 많이 클릭하면 갑자기 메모리사용량이 기하급수적으로 늘어나고, 시간이 지나서 요청을 모두 처리해도 메모리가 해제되지 않는 문제를 만났습니다. 현재(2023.11)까지 제가 프로젝트를 하며 만났던 문제 중 가장 막막했던 문제였습니다.
아무리 plt.clf()
, plt.close('all')
, del
, gc.collect()
등을 사용한다고 해도 해결이 되지 않고, 구글링 해보아도 저와 비슷한 문제를 겪은 사람을 볼 수 있었는데, 해결한 사례를 찾지 못하였습니다.
이렇게 되면 누수되는 것 자체는 해결하지 못하고, 다른 방식으로 해결해야 할 것 같네요.
결국
결국 여러 가지 방법을 사용하여 어느 정도 해결하였습니다.
- Nginx로 동시에 많은 요청 방지
- 동시에 많은 요청 자체가 힘들도록 요청버튼 한번 클릭 시 버튼 비활성화
- gunicorn을 이용한 프로세스 관리
Nginx와 gunicorn에 관한 자세한 내용은 이후 다른 포스팅에서 다뤄볼 예정입니다.
'프로젝트' 카테고리의 다른 글
웹 프로젝트 - 8. AWS 청구서 분석1 (EC2, CPU 크레딧, EBS 볼륨 스냅샷) (0) | 2024.02.17 |
---|---|
7. Redis(레디스)의 유용한 기능 - 도커 컨테이너간 정보공유 (0) | 2024.02.17 |
프로젝트 - 5. 데이터 파이프라인, 데이터베이스 구조 정리 (0) | 2024.02.17 |
비슷한 차트 탐색 프로젝트 - 4. AWS를 사용해서 배포해보자 (0) | 2024.02.17 |
비슷한 차트 탐색 프로젝트 - 3. 프로젝트를 Docker로 구성해보자 (0) | 2024.02.17 |