Как немедленно освободить используемую память в списке python? - программирование
Подтвердить что ты не робот

Как немедленно освободить используемую память в списке python?

во многих случаях вы уверены, что определенно не будете использовать список снова, я надеюсь, что память должна быть выпущена прямо сейчас

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

Я не уверен, действительно ли он освобождает память, вы можете использовать

del a[:]

которые фактически удаляют все элементы в списке a.

так лучший способ его освободить?

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

не совсем уверен. Вы высказали свое мнение.

btw, как насчет кортежа и набора?

4b9b3361

Ответ 1

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

Никогда не делай этого. Python автоматически освобождает все объекты, на которые не ссылаются больше, поэтому простой del a гарантирует, что память списка будет выпущена, если в списке больше нет ссылок. В этом случае отдельные элементы списка также будут освобождены (и любые объекты, на которые ссылаются только они, и т.д. И т.д.), Если только некоторые из отдельных элементов также не упоминаются.

Это означает, что только время, когда del a[:]; del a будет выпускать больше, чем del a самостоятельно, это когда список ссылается где-то в другом месте. Это точно, когда вы не должны выгружать список: кто-то еще его использует!!!

В принципе, вы не должны думать об управлении фрагментами памяти. Вместо этого подумайте об управлении ссылками на объекты. В 99% всего кода Python Python очищает все, что вам не нужно, довольно скоро после того, как в последний раз вам это нужно, и проблем нет. Каждый раз, когда функция заканчивает все локальные переменные в этой функции "die", и если они указывают на объекты, которые не упоминаются нигде, они будут удалены, и это будет каскадироваться ко всему, что содержится в этих объектах.

Единственный раз, когда вам нужно подумать об этом, - когда у вас есть большой объект (скажем, огромный список), вы что-то делаете с ним, а затем начинаете длительный (или интенсивный) подсчет вычислений, где для суб-вычисления не требуется большой объект. Поскольку у вас есть ссылка на него, большой объект не будет выпущен до тех пор, пока суб-вычисление не закончится, а затем вы вернетесь. В таком случае (и только в этом случае) вы можете явно del ссылаться на большой объект перед тем, как приступить к суб-вычислению, так что большой объект может быть освобожден раньше (если никто не используя его, если вызывающий объект передал вам объект, а вызывающий сделал все еще нуждался в нем после того, как вы вернетесь, вы будете очень рады, что он не будет выпущен).

Ответ 2

Как отмечает @monkut, вы, вероятно, не должны слишком беспокоиться об управлении памятью в большинстве ситуаций. Если у вас есть гигантский список, с которым вы уверены, что с ним все закончилось, и он не выйдет из текущей области действия на некоторое время:

del a просто удаляет ваше имя a для этого фрагмента памяти. Если какая-либо другая функция или структура или что-то еще ссылается на нее, она не будет удалена; если этот код имеет единственную ссылку на этот список под именем a, и вы используете CPython, эталонный счетчик немедленно освободит эту память. Другие реализации (PyPy, Jython, IronPython) могут не убить его сразу, потому что у них разные сборщики мусора.

Из-за этого оператор del a в вашей функции realse_list фактически ничего не делает, потому что у вызывающего все еще есть ссылка!

del a[:] будет, как вы заметили, удалить элементы из списка и, следовательно, большую часть использования памяти.

Вы можете сделать the_set.clear() для аналогичного поведения с наборами.

Все, что вы можете сделать с кортежем, потому что они неизменяемы, del the_tuple и надеюсь, что никто другой не ссылается на него, но вы, вероятно, не должны иметь огромные кортежи!

Ответ 3

Python использует количество ссылок для управления своим ресурсом.

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 также уменьшается. Итак, в вашем коде

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

был избыточным.

В общем, все, что вам нужно сделать, это присвоить список объекту None или использовать ключевое слово del, чтобы удалить список из словаря атрибутов. (a.k.a, чтобы отвязать имя от фактического объекта). Например,

a = None # or
del a

Когда счетчик ссылок объекта обращается в нуль, python освободит память для вас. Чтобы убедиться, что объект удален, вы должны убедиться, что никакие другие места не ссылаются на объект по имени или по контейнеру.

sys.getrefcount(b) # gives 2

Если sys.getrefcount дает вам 2, это означает, что вы единственный, у кого была ссылка на объект и когда вы делаете

b = None

он освободится из памяти.

Ответ 4

Если вы беспокоитесь об управлении памятью и производительности для типов данных, почему бы не использовать что-то вроде связанной двойной очереди.

Сначала его память отстает от памяти, поэтому вам не придется выделять большой кусок непрерывной памяти сразу с места в карьер.

Во-вторых, вы увидите более быстрое время доступа для enqueueing и dequeueing, потому что, в отличие от стандартного списка, когда вы удаляете, можно сказать, что средний элемент не нужен для сдвига остальной части списка в индексе, который занимает много времени в больших списках.

Я также должен отметить, что если вы используете только целые числа, я бы предложил посмотреть в двоичную кучу, поскольку вы увидите время доступа O (log ^ 2n) по сравнению с главным образом O (N) со списками.