2012-09-14 2 views
17

, 당신은 확실히 목록을 다시 사용하지 않을, 내가 정말 메모리를 해제하면 메모리가 지금파이썬 목록에서 사용한 메모리를 즉시 해제하는 방법은 무엇입니까? 많은 경우에

a = [11,22,34,567,9999] 
del a 

잘 모르겠어요 해제해야 희망을 확신합니다, 당신은 사용할 수 있습니다

del a[:] 

실제로 목록의 모든 요소가 제거됩니다.

그래서 가장 좋은 방법은 무엇입니까?

def realse_list(a): 
    del a[:] 
    del a 

귀하의 의견을 필요로합니다.

btw, 튜플 및 세트는 어떨까요?

+9

많은 양의 데이터를 처리하고 실제로 MemoryError 예외가 발생하지 않는 한 메모리 관리에 대해 걱정하지 마십시오. – monkut

답변

19
def release_list(a): 
    del a[:] 
    del a 

이 작업을 수행하지 마십시오. Python은 더 이상 참조되지 않은 모든 객체를 자동으로 해제하므로 간단한 del a은 목록이 다른 곳에서 참조되지 않으면 목록의 메모리가 해제되도록합니다. 이 경우 개별 항목 중 일부가 계속 참조되지 않는 한 개별 목록 항목도 해제됩니다 (및 해당 항목에서만 참조되는 개체 등). 목록이 다른 곳에서 참조 할 때 del a[:]; del a 자체에 이상 del a을 해제 할 시간을 의미

이다. 이 비어 있지 않아야합니다. 다른 사람이 아직 사용하고 있습니다!

기본적으로 메모리 관리에 대해 생각하지 않아야합니다. 대신 객체에 대한 참조 관리에 대해 생각해보십시오.모든 파이썬 코드의 99 %에서 파이썬은 당신이 마지막으로 필요로했던 시간이 지나면 필요없는 모든 것을 정리합니다. 아무런 문제가 없습니다. 함수가 "죽는다"는 함수의 모든 지역 변수가 끝날 때마다, 그리고 다른 곳에서 참조되지 않은 객체를 가리키고 있다면 그 객체는 삭제되고 그 객체에 포함 된 모든 객체에 캐스 캐 이드됩니다.

큰 오브젝트 (거대한리스트)를 가지고 뭔가를하고 장기 실행 (또는 메모리 집약적 인) 하위 계산을 시작할 때만 생각하면됩니다. 여기서 큰 객체 은 하위 계산에 필요한이 아닙니다. 그것에 대한 참조가 있기 때문에 하위 계산이 끝날 때까지 대형 객체가 해제 된 다음 반환됩니다. 이런 종류의 경우 (그 경우에만), 하위 계산을 시작하기 전에 큰 개체에 대한 참조를 명시 적으로 del 수 있으므로 큰 개체를 더 빨리 해제 할 수 있습니다 (아무도없는 경우). 이를 사용하여 호출자가 객체를 당신에게 전달하고 호출자 을 반환 한 후에도 여전히 필요하면 매우이 출시되지 않기 때문에 기쁠 것입니다.

+0

** a **가 회원 변수 (큰 변수)이고 더 이상 사용하지 않는다는 것을 알고 싶다면이 변수를 "참조 된 변수"로 간주합니까? 시나리오는 간단합니다. _when_needed_ 큰 목록을 처리하는 개체가 있습니다. 일부 메소드가 호출 된 후 ** a ** 목록이 처리되고 결과를 캐시합니다. 이 경우 나는 내가 더 이상 ** 필요가 없다는 것을 안다. – hsgubert

+1

@hsgubert'a'가 어떤 객체 (멤버 변수)의 속성이라면 그 객체의 일부가 참조됩니다 (객체 자체가 어딘가에서 참조된다고 가정). 그러나 더 이상 필요가 없다는 것을 알고 계시다면 같은 계급의 방법을 사용하고 계실 것입니다. 만약 당신이 그 계급의 방법에 있지 않다면, 그것을 버리지 마십시오. 좋은 디자인은 거의 항상 각 클래스가 자체 속성 관리를 담당하도록합니다. 프로그램의 다른 부분이 객체가 그 속성 중 하나를 더 이상 필요로하지 않는다고 무작위로 결정할 수 있다면 클래스를 이해하는 것은 매우 어렵습니다. – Ben

4

@monkut 메모와 같이 대부분의 상황에서 메모리 관리에 대해 너무 걱정하지 않아도됩니다.

del a은 단순히 그것을 위해 당신의 이름 a을 제거 : 당신은 당신이 지금으로 완료하고 있지만, 잠시 동안 현재 함수의 범위 밖으로 이동하지 않습니다 확신 거대한 목록이있는 경우 메모리 덩어리. 다른 함수 나 구조체 또는 그 참조를 계속 참조하면 삭제되지 않습니다. 이 코드가 a이라는 이름으로 해당 목록에 대한 유일한 참조를 갖고 있고 CPython을 사용하고 있다면 참조 카운터가 즉시 해당 메모리를 해제합니다. 다른 구현 (PyPy, Jython, IronPython)은 가비지 컬렉터가 다르기 때문에 즉시 삭제할 수 없습니다.

따라서 realse_list 함수의 del a 문은 호출자가 여전히 참조를 가지고 있기 때문에 실제로 아무 것도하지 않습니다!

del a[:]은 목록에서 요소를 제거하므로 아마도 대부분의 메모리 사용이 가능할 것입니다.

집합과 비슷한 동작에 대해 the_set.clear()을 수행 할 수 있습니다.

튜플을 사용할 수있는 것은 모두 불변이므로 del the_tuple이며 아무도 다른 튜토리얼에 대한 참조가 없기를 바랍니다. 그러나 엄청난 튜플이 있어서는 안됩니다.

+1

이 답변은 약한 참조에 대한 논의를 통해 훨씬 더 완전해질 것입니다. – Marcin

1

데이터 유형에 대한 메모리 관리 및 성능에 대해 걱정한다면 왜 링크 된 이중 대기열과 같은 것을 사용하지 않을까요?

먼저 메모리 공간이 메모리에 흩어져 있으므로 방망이에서 연속적으로 많은 메모리를 할당 할 필요가 없습니다.

둘째, 기본 목록에서 제거 할 때와 달리 중간 목록에서 나머지 목록을 색인에 밀어 넣을 필요가 없으므로 대기열에 추가하거나 대기열에서 제외하는 것이 더 빠릅니다 .

정수 만 사용하는 경우 O (log^2n) 액세스 시간이 목록의 O (N) 액세스 시간과 비교하면 이진 힙을 조사하는 것이 좋습니다.

2

파이썬은 Reference Count을 사용하여 리소스를 관리합니다. 당신이 목록에 넣어 때

import sys 
class foo: 
    pass 

b = foo() 
a = [b, 1] 

sys.getrefcount(b) # gives 3 
sys.getrefcount(a) # gives 2 

a = None # delete the list 
sys.getrefcount(b) # gives 2 

는 위의 예에서, B의 참조 카운트가 증가 될 것이며, 당신이 볼 수있는 당신이 목록을 삭제하면, B의 참조 횟수도 감소 얻을. 따라서 귀하의 코드에

def release_list(a): 
    del a[:] 
    del a 

은 중복되었습니다.

요약하면 목록을 None 개체에 할당하거나 del 키워드를 사용하여 특성 사전에서 목록을 제거하면됩니다. (a.k.a, 실제 객체의 이름을 바인딩 해제). 예 :

a = None # or 
del a 

개체의 참조 횟수가 0이되면 파이썬은 메모리를 확보합니다. 개체가 삭제되는지 확인하려면 개체를 이름이나 컨테이너로 참조하는 다른 작업 영역이 없는지 확인해야합니다. sys.getrefcount 당신에게 2를 제공하는 경우

sys.getrefcount(b) # gives 2 

, 그건 당신이 개체의 참조를 가지고있는 유일한 사람이고, 당신이

b = None 

을 수행 할 때이 메모리에서 해제받을 것을 의미합니다.

관련 문제