2016-06-02 3 views
2

Похоже, сборщик мусора не собирает значения pop 'd из dict() в python 2.7 (не пытался на python 3). Вот пример:dict pop не освобождает память

a = dict() 

# fill the memory (dict) 
for i in xrange(0, 9999999): 
    a[i] = i 

# Memory usage is about 600 MB 
# try to free the memory 
for i in xrange(0, 9999999): 
    a.pop(i) 

# print the dict and see it is empty 
print "%r" % a 
# prints: {} 
# Memory usage is about 600 MB 

import copy 
a = copy.copy(a) 
# Memory usage decreased to about 200 MB 

import gc 
gc.collect() 
# Memory usage decreased to about 10 MB  

Кто-нибудь знает, почему это происходит и как решить эту проблему утечки памяти?

+0

как вы измерили использование памяти? – Daniel

+0

с помощью команды 'top' –

+0

Зачем использовать' pop', а не 'del'? –

ответ

4

Проблема с утечкой памяти отсутствует, поскольку память освобождается, когда словарь больше не используется. Словари используют внутренние таблицы для хранения записей. Эти таблицы не освобождаются при использовании pop, поскольку каждый ключ сопоставляется с размером хэша по модулю внутренней таблицы. Таким образом, последний существующий ключ может лежать в конце этой таблицы.

Чтобы проиллюстрировать это, я буду использовать sys.getsizeof:

>>> a= {} 
>>> sys.getsizeof(a) 
288 
>>> for i in range(9999999): a[i]=i 
... 
>>> sys.getsizeof(a) 
402653280 
>>> for i in range(9999999): del a[i] 
... 
>>> sys.getsizeof(a) 
402653280 
>>> a = copy.copy(a) 
>>> sys.getsizeof(a) 
288 
>>> 

Вместо использования чрезмерных pop с, вы должны создать новые словари, если это необходимо.

+0

Я повторил этот эксперимент с помощью списка 'a = []' и 'a.pop()', и похоже, что в этом случае освобождает память, правильно ли это звучит? – pinhead