2017-10-03 20 views
0

내 패키지에서 실행중인 일부 코드가 있으며 프로그램이 있어야하는 것보다 많은 메모리 (60GB)를 사용하고 있습니다. 이 메모리가 사용되는 위치를 찾기 위해 현재 네임 스페이스에서 모든 개체의 크기 (바이트)를 어떻게 인쇄 할 수 있습니까? 파이썬 : 현재 네임 스페이스에있는 모든 객체의 크기를 얻는 방법은 무엇입니까?

나는

from pympler import asizeof 

for objname in dir(): 
    print(asizeof.asizeof(thing)/1024) # print size in kb 

뭔가를 시도하지만 그냥 네임 스페이스에있는 개체의 이름이 포함 된 문자열의 크기를 출력으로 작동하지 않습니다. 이 방법을 사용하기 위해 네임 스페이스의 모든 것에 대한 객체 참조를 얻는 방법이 있습니까? 아니면 메모리를 사용하고있는 것의 해결을위한 더 나은 방법이 있습니까?

+0

예,'dir()'은 단지 이름 *을 문자열로 생성합니다. 'globals()'와'locals()'를 사용하여 네임 스페이스를 사전으로 가져 오면, 이름이 아닌 객체 자체에 액세스 할 수 있습니다. –

답변

3

dir()은 로컬 범위에있는 이름 만 반환합니다. 사전으로 로컬 범위를 얻기 위해 locals() function를 사용

for obj in locals().values(): 
     print(asizeof.asizeof(obj)/1024) 

주 기능의 외부 locals()globals()와 같은 매핑입니다. asizeof()이 사전에있는 경우

, 당신은 그것을 필터링 할 : 인수없이

for name, obj in locals().items(): 
    if name != 'asizeof': 
     print(asizeof.asizeof(obj)/1024) 

dir()sorted(locals()) (로컬 네임 스페이스 키의 정렬 된 목록)과 기능적으로 동일합니다.

+0

이것을 실행할 때 재귀 문제가 발생하는 것으로 보입니다. 내 생각에 asizeof가 자체적으로 실행되기 때문에 locals()가 만든 dict에서 이것을 제거하는 간단한 방법이 있습니까? – SomeRandomPhysicist

+0

@SomeRandomPhysicist :'dict.items()'이름 - 값 쌍을 반복하여 필터링 할 수 있습니다. 또는'obj가 asizeof가 아닌 경우 :'를 사용하십시오. –

+0

asizeof를 참조하는 여러 임시 변수가 있으므로 더 일반적인 필터링 방법은 단순히 try except 문을 사용하는 것입니다. – SomeRandomPhysicist

1

gc.get_objects()을 사용하면 특정 네임 스페이스에있는 개체뿐만 아니라 수집기에서 추적 한 모든 개체를 가져올 수 있습니다. 나는 그것이 당신에게 그 자체로 단서를 줄지 모르기 때문에 그것을 사용하여 각 유형의 인스턴스의 수를 세는 것으로 시작할 것입니다.

from collections import Counter 
c = Counter(type(o) for o in gc.get_objects()) 
print(c.most_common(20)) 

그렇다면 가능성이있는 용의자의 크기를 찾아보십시오.

+2

참. 나는 그것을 업데이트했다. 무한 루프를 피하려면 여전히 조심해야하지만'get_objects() '는 과거의 메모리 누수에 대한 유용한 출발점이었다. – Duncan