Быстрый в изучении - мощный в программировании
>> Telegram ЧАТ для Python Программистов

Свободное общение и помощь советом и решением проблем с кодом! Заходите в наш TELEGRAM ЧАТ!

>> Python Форум Помощи!

Мы создали форум где отвечаем на все вопросы связанные с языком программирования Python. Ждем вас там!

>> Python Канал в Telegram

Обучающие статьи, видео и новости из мира Python. Подпишитесь на наш TELEGRAM КАНАЛ!

Подсчет ссылок и сборка мусора в Python

26 ноября 2015 г. Archy Просмотров: 18384 RSS
Python для начинающих
Подсчет ссылок и сборка мусора в Python

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

a = 37 # Создается объект со значением 37
b = a  # Увеличивается счетчик ссылок на объект 37
c = []
c.append(b) # Увеличивается счетчик ссылок на объект 37

В этом примере создается единственный объект, содержащий значение 37. Переменная a, это всего лишь имя, ссылающееся переменной b, вслед чего b становится еще одним именем того же самого объекта, при этом счетчик ссылок на объект увеличивается на 1. Точно так же, когда переменная b помещается в список, счетчик ссылок увеличивается на единицу.

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

Счетчик ссылок уменьшается, когда вызывается инструкция del или когда поток выполнения покидает область видимости ссылки(или при присваивании другого значения). Например:

del a   # Уменьшает счетчик ссылок на объект 37
b = 42  # Уменьшает счетчик ссылок на объект 37
с[0] = 2.0 # Уменьшает счетчик ссылок на объект 37

Определить текущее количество ссылок на объект можно с помощью функции sys.getrefcount(). Например, создаем переменную Иван Франко которая будет ссылаться на строку "критика на творчество Франко".

>>> a = 37
>>> import sys
>>> IvanFranko = "критика на творчество Франко"
>>> length = len(IvanFranko) # длина строки
>>> sys.getrefcount(IvanFranko)
2
>>> sys.getrefcount(length)
9
>>> length
28

Собственно, на Ubuntu все выглядит следующим образом:

Подсчет ссылок и сборка мусора в Python

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

На сайте https://doctorsmm.com/ можно купить очень недорогие комментарии в Инстаграм к любому посту или нескольким публикациям сразу. При этом Вы вправе выбрать формат сообщений: рандомные, смайлы, живые или микс.

Когда счетчик ссылок на объект достигает нуля, он уничтожается сборщиком мусора. Однако в некоторых случаях могут возникать циклические зависимости между коллекциями объектов, которые больше не используются. Например:

a = {}
b = {}
a['b'] = b # a содержит ссылку на b
b['a'] = a # b содержит ссылку на a
del a
del b

В этом примере инструкция del уменьшает счетчики ссылок на объекты a и b и уничтожает имена, ссылавшиеся на объекты в памяти. Однако поскольку объекты содержат ссылки друг на друга, счетчики ссылок не достигают нуля и объекты продолжают существовать(что приводит к утечке памяти).

Чтобы исправить эту проблему, интерпретатор периодически выполняет проверку наличия циклических зависимостей, отыскивает такие недоступные объекты и удаляет их. Механизм поиска циклических зависимостей запускается периодически, как только интерпретатор обнаруживает, что в процессе выполнения программы объем занимаемой памяти начинает расти. Точное поведение механизма может корректироваться и управляться с помощью функции из модуля gc.