Python 메모리 누수
장기 실행 중인 스크립트가 있습니다.이 스크립트를 충분히 실행하면 시스템상의 모든 메모리가 소비됩니다.
스크립트에 대한 자세한 내용은 생략하고 두 가지 질문이 있습니다.
- 누출 발생을 방지하는 데 도움이 되는 "베스트 프랙티스"가 있습니까?
- Python에서 메모리 누수를 디버깅하는 기술은 무엇입니까?
이 기사를 보세요.python 메모리 누수를 추적하고 있습니다.
또한 가비지 수집 모듈에는 실제로 디버깅플래그가 설정되어 있을 수 있습니다.를 봐주세요.set_debug
기능.게다가 콜 후에 작성된 오브젝트의 종류를 판별하려면 , Gnibbler 의 이 코드를 참조해 주세요.
이전에 언급한 대부분의 옵션을 사용해 보았습니다만, 이 작고 직관적인 패키지가 가장 좋다고 생각합니다.: pympler
가비지 수집되지 않은 개체를 추적하는 것은 매우 간단합니다. 다음 작은 예를 확인하십시오.
패키지를 설치하다pip install pympler
from pympler.tracker import SummaryTracker
tracker = SummaryTracker()
# ... some code you want to investigate ...
tracker.print_diff()
출력에는 추가된 모든 개체와 사용된 메모리가 표시됩니다.
샘플 출력:
types | # objects | total size
====================================== | =========== | ============
list | 1095 | 160.78 KB
str | 1093 | 66.33 KB
int | 120 | 2.81 KB
dict | 3 | 840 B
frame (codename: create_summary) | 1 | 560 B
frame (codename: print_diff) | 1 | 480 B
이 패키지는 많은 기능을 제공합니다.Pympler의 매뉴얼, 특히 메모리 누전 식별 섹션을 참조하십시오.
작성한 mem_top 툴을 추천합니다.
그것은 비슷한 문제를 해결하는 데 도움이 되었다.
Python 프로그램에서 메모리 누수의 주요 용의자를 즉시 보여줍니다.
Tracemalloc 모듈은 Python 3.4부터 내장 모듈로 통합되었으며, 분명히 이전 버전의 Python에서도 서드파티 라이브러리로 사용할 수 있습니다(테스트되지 않았습니다).
이 모듈은 가장 많은 메모리를 할당한 정확한 파일과 행을 출력할 수 있습니다.IMHO, 이 정보는 각 유형에 할당된 인스턴스의 수보다 훨씬 중요합니다(이것은 결국 99%의 많은 튜플이 됩니다.이것은 단서가 되지만, 대부분의 경우 거의 도움이 되지 않습니다).
트레이스몰록을 피라사이트와 조합하여 사용하는 것을 추천합니다.10번 중 9번 피라사이트 쉘에서 상위 10개의 스니펫을 실행하면 누출을 10분 이내에 해결할 수 있는 충분한 정보와 힌트를 얻을 수 있습니다.그러나 여전히 누출 원인을 찾을 수 없는 경우, 이 스레드에 언급된 다른 도구와 함께 피라사이트 쉘을 사용하면 더 많은 힌트를 얻을 수 있습니다.또한 Pyrasite(메모리 뷰어 등)에 의해 제공되는 모든 추가 도우미도 확인해야 합니다.
특히 글로벌 데이터 또는 정적 데이터(장수 데이터)를 확인해야 합니다.
이 데이터가 제한 없이 증가하면 Python에서도 문제가 발생할 수 있습니다.
가비지 컬렉터는 더 이상 참조되지 않는 데이터만 수집할 수 있습니다.그러나 정적 데이터는 개방해야 할 데이터 요소를 연결할 수 있습니다.
또 다른 문제는 메모리 사이클일 수 있지만 적어도 이론적으로는 가비지 컬렉터가 긴 수명 데이터에 접속되어 있지 않은 한 사이클을 찾아 제거해야 합니다.
특히 문제가 되는 장수 데이터는 어떤 것입니까?목록과 사전을 잘 살펴보세요. 무제한으로 확장할 수 있습니다.딕트에 액세스 할 때, 사전에 있는 키의 수가 그다지 눈에 띄지 않는 경우가 있기 때문에, 사전에서는 문제가 발생하지 않을 수도 있습니다.
이제 stackimpact를 사용하여 프로덕션 환경 등 장기간 실행 중인 프로세스의 메모리 누수를 감지하고 찾을 수 있습니다.밑에 tracemalloc을 사용합니다.자세한 것은, 이 투고입니다.
베스트 프랙티스에 관해서는 재귀 함수를 주시해 주십시오.제 경우 재귀에 문제가 있었습니다(필요가 없는 경우).내가 하고 있던 일의 간단한 예:
def my_function():
# lots of memory intensive operations
# like operating on images or huge dictionaries and lists
.....
my_flag = True
if my_flag: # restart the function if a certain flag is true
my_function()
def main():
my_function()
이 재귀적인 방식으로 작동하면 가비지 컬렉션이 트리거되지 않고 함수의 나머지 부분이 지워지므로 메모리 사용량이 계속 증가하고 있습니다.
my_function()에서 재귀 호출을 꺼내 다시 호출할 때 main() 핸들을 갖는 것이 해결책이었습니다.이렇게 하면 기능은 자연스럽게 끝나고 저절로 정리됩니다.
def my_function():
# lots of memory intensive operations
# like operating on images or huge dictionaries and lists
.....
my_flag = True
.....
return my_flag
def main():
result = my_function()
if result:
my_function()
python의 메모리 누전에 대한 "베스트 프랙티스"에 대해서는 확실하지 않지만 python은 가비지 컬렉터에 의해 자신의 메모리를 클리어해야 합니다.그래서 저는 주로 짧은 순환 목록을 확인하는 것부터 시작하겠습니다. 쓰레기 수집기에 의해 수거되지 않기 때문입니다.
이것은 결코 포괄적인 충고는 아니다.단, 미래의 메모리누전(루프)을 회피하기 위해 쓸 때는 콜백에 대한 참조를 받아들이는 모든 것이 그 콜백을 취약한 참조로 저장해야 한다는 점에 유의해야 합니다.
언급URL : https://stackoverflow.com/questions/1435415/python-memory-leaks
'programing' 카테고리의 다른 글
mysql: Whoami? (0) | 2022.11.03 |
---|---|
Python을 사용하여 OpenCV에서 이미지를 자르는 방법 (0) | 2022.11.03 |
아래 쿼리에서 테이블을 만드는 동안 오류가 발생했습니다. (0) | 2022.11.03 |
사람이 읽을 수 있는 파일 크기 버전을 가져오시겠습니까? (0) | 2022.11.03 |
vuex: 네임슬레이드모듈 내에서 콜 변환이 필요한 이유는 무엇입니까? (0) | 2022.11.03 |