python의 세 가지 흔히 볼 수 있는 메모리 유출 장면을 총괄하다
Python이 자동 쓰레기 회수가 있으면 메모리 누출이 없다고 생각하지 마라. 쓰레기 회수가 있기 때문에 나는'스팸 코드'의 정신을 가지고 있다. 지금 세 가지 흔히 볼 수 있는 메모리 누출 장면을 총괄해 보자.
무궁무진하게 메모리 유출을 초래하다
만약 메모리 유출을 신청만 하고 방출하지 않는다고 정의한다면,Python의 정수를 빌려 무한대의 이 특징을 빌려 우리 코드는 메모리 유출을 완성할 수 있다.
i = 1024 ** 1024 ** 1024
순환 인용으로 메모리 유출인용 기수기는 Python 쓰레기 회수 메커니즘의 기초이다. 만약에 대상의 인용 수량이 0이 되지 않으면 쓰레기가 회수되지 않는다. 우리는sys를 통해getrefcount는 주어진 대상의 인용 수량을 얻습니다.
In [1]: import sys
In [2]: a = {'name':'tom','age':16}
In [3]: sys.getrefcount(a) # getrefcount a , 2 。
Out[3]: 2
In [4]: b = a
In [5]: sys.getrefcount(a)
Out[5]: 3
먼저 순환 인용 장면을 보십시오.
#!/usr/bin/evn python3
import sys
import time
import threading
class Person(object):
free_lock = threading.Condition()
def __init__(self, name: str = ""):
"""
Parameters
----------
name: str
best_friend: str
"""
self._name = name
self._best_friend = None
@property
def best_friend(self, person: "Person"):
return self._best_friend
@best_friend.setter
def best_friend(self, friend: "Person"):
self._best_friend = friend
def __str__(self):
"""
"""
return self._name
def __del__(self):
"""
"""
self.free_lock.acquire()
print(f"{self._name} GG , 。")
sys.stderr.flush()
self.free_lock.release()
def mem_leak():
"""
"""
zhang_san = Person(name=' ')
li_si = Person(" ")
#
#
li_si.best_friend = zhang_san
#
zhang_san.best_friend = li_si
if __name__ == "__main__":
for i in range(3):
time.sleep(0.01)
print(f"{i}")
mem_leak()
print("mem_leak .")
time.sleep(5)
실행 효과.python3 main.py
0
일
이
mem_leak 실행이 완료되었습니다.
장삼은 GG를 원하는데, 지금 그것의 메모리 공간을 방출한다.
이사는 GG를 원한다. 이제 메모리 공간을 방출한다.
장삼은 GG를 원하는데, 지금 그것의 메모리 공간을 방출한다.
이사는 GG를 원한다. 이제 메모리 공간을 방출한다.
장삼은 GG를 원하는데, 지금 그것의 메모리 공간을 방출한다.
이사는 GG를 원한다. 이제 메모리 공간을 방출한다
순환 인용의 존재로 인해mem_leak 함수만 실행하면 그 내부의 국부 변수 인용 계수기도 0이 아니기 때문에 메모리가 제때에 방출되지 않습니다.이 부분의 메모리를 방출하는 데는 두 가지 경로가 있다. 1,Python 내부의 순환 검출 메커니즘에 의해 발견되었다.2. 프로세스가 종료되기 전의 집중 방출.
tracemalloc 일정한 절차에서 우리가 문제를 발견하는 것을 도울 수 있다. 여기서 어떻게 사용하는지 말하지 않고 우리는 직접 해결 방안을 제시한다.Python은 프로그래머에게 약한 인용을 제공합니다. 이런 방식을 통해 대상 인용 계수기의 수치를 증가하지 않을 수 있습니다. 이것은 우리가 순환 인용을 깨뜨리는 수단이 되었습니다.
In [1]: import sys
In [2]: import weakref
In [3]: from main import Person
In [4]: tom = Person('tom')
In [5]: sys.getrefcount(tom)
Out[5]: 2
In [6]: p = weakref.ref(tom)
In [7]: sys.getrefcount(tom) #
Out[7]: 2
현재 weakref 기술을 사용하여 우리의 코드를 개조합니다.
#!/usr/bin/evn python3
import sys
import time
import weakref
import threading
class Person(object):
free_lock = threading.Condition()
def __init__(self, name: str = ""):
"""
Parameters
----------
name: str
best_friend: str
"""
self._name = name
self._best_friend = None
@property
def best_friend(self, person: "Person"):
return self._best_friend
@best_friend.setter
def best_friend(self, friend: "Person"):
self._best_friend = weakref.ref(friend)
def __str__(self):
"""
"""
return self._name
def __del__(self):
"""
"""
self.free_lock.acquire()
print(f"{self._name} GG , 。")
sys.stderr.flush()
self.free_lock.release()
def mem_leak():
"""
"""
zhang_san = Person(name=' ')
li_si = Person(" ")
#
#
li_si.best_friend = zhang_san
#
zhang_san.best_friend = li_si
if __name__ == "__main__":
for i in range(3):
time.sleep(0.01)
print(f"{i}")
mem_leak()
print("mem_leak .")
time.sleep(5)
실행 효과.python3 main.py
0
장삼은 GG를 원하는데, 지금 그것의 메모리 공간을 방출한다.
이사는 GG를 원한다. 이제 메모리 공간을 방출한다.
일
장삼은 GG를 원하는데, 지금 그것의 메모리 공간을 방출한다.
이사는 GG를 원한다. 이제 메모리 공간을 방출한다.
이
장삼은 GG를 원하는데, 지금 그것의 메모리 공간을 방출한다.
이사는 GG를 원한다. 이제 메모리 공간을 방출한다.
mem_leak 실행이 완료되었습니다.
현재 함수 실행이 완료되면 그 내부의 국부 변수의 메모리가 방출되고 매우 신속하다는 것을 볼 수 있다.
외부 라이브러리가 메모리 유출을 초래하다
이런 상황은 나도 단지 한 번 만난 적이 있다. 이전에 mysql-connector-python의 메모리 유출로 인해 나의 프로그램이 달리면서 차지하는 메모리가 점점 커진다.마지막으로 우리가 되돌아온 C 언어의 확장이 비활성화되면 문제가 없다.
이상은python의 세 가지 흔히 볼 수 있는 메모리 유출 장면의 상세한 내용을 총괄하고python 메모리 유출에 관한 더 많은 자료는 저희 다른 관련 글에 주목하세요!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
로마 숫자를 정수로 또는 그 반대로 변환그 중 하나는 로마 숫자를 정수로 변환하는 함수를 만드는 것이었고 두 번째는 그 반대를 수행하는 함수를 만드는 것이었습니다. 문자만 포함합니다'I', 'V', 'X', 'L', 'C', 'D', 'M' ; 문자열이 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.