Как правило, вам не нужно беспокоиться о сборщике мусора и работе с памятью когда вы пишете код на Python. Как только объекты больше не нужны, Python автоматически освобождает память из под них. Несмотря на это, понимание как работает GC поможет писать более качественный код.
Менеджер памяти
В отличие от других популярных языков, Python не освобождает всю память обратно операционной системе как только он удаляет какой либо объект. Вместо этого, он использует дополнительный менеджер памяти, предназначенный для маленьких объектов (размер которых меньше чем 512 байт). Для работы с такими объектами он выделяет большие блоки памяти, в которых в дальнейшем будет хранится множество маленьких объектов.
Как только один из маленьких объект удаляется — память из под него не переходит операционной системе, Python оставляет её для новых объектов с таким же размером. Если в одном из выделенных блоков памяти не осталось объектов, то Python может высвободить его операционной системе. Как правило, высвобождение блоков случается когда скрипт создает множество временных объектов.
Цикличный сборщик в Thermal Expansion
Таким образом, если долгоживущий Python процесс с течением времени начинает потреблять больше памяти, то это совсем не означает, что в вашем коде есть проблема с утечкой памяти. Если вы хотите узнать больше о менеджере памяти в Python, вы можете прочитать об этом в другой моей статье (англ.).
Алгоритмы сборки мусора
Стандартный интерпретатор питона (CPython) использует сразу два алгоритма, подсчет ссылок и generational garbage collector (далее GC), более известный как стандартный модуль gc из Python.
Алгоритм подсчета ссылок очень простой и эффективный, но у него есть один большой недостаток. Он не умеет определять циклические ссылки. Именно из-за этого, в питоне существует дополнительный сборщик, именуемый поколенческий GC, который следит за объектами с потенциальными циклическими ссылками.
В Python, алгоритм подсчета ссылок является фундаментальным и не может отключен, тогда как GC опционален и может быть отключен.
Алгоритм подсчета ссылок
Алгоритм подсчета ссылок это одна из самых простых техник для сборки мусора. Объекты удаляются как только на них больше нет ссылок.
В Python, переменные не хранят значения, а выступают в роли ссылок на объекты. То есть когда вы присваивайте значение новой переменной, то сначала создается объект с этим значением, а уже потом переменная начинает ссылаться на него. На один объект может ссылаться множество переменных.
Каждый объект в Python содержит дополнительное поле (счетчик ссылок), в котором хранится количество ссылок на него. Как только кто-то ссылается на объект, это поле увеличивается на единицу. Если по какой-то причине ссылка пропадает, то это поле уменьшается на один.
Примеры, когда количество ссылок увеличивается:
- оператор присваивания
- передача аргументов
- вставка нового объекта в лист (увеличивается количество ссылок для объекта)
- конструция вида foo = bar (foo начинается ссылаться на тот же объект, что и bar)
Например, если удаляется список, то счетчик ссылок во всех его элементах уменьшается на один. Если все объекты внутри списка больше нигде не используются, то они также будут удалены.
Переменные, которые объявлены вне функций, классов и блоков называются глобальными. Как правило, жизненный цикл таких переменных равен жизни Python процесса. Таким образом, количество ссылок на объекты на которые ссылаются глобальные переменные никогда не падает до нуля.
Переменные, которые объявлены внутри блока (функции, класса) имеют локальную видимость (т.е. они видны только внутри блока). Как только интерпретатор питона выходит из блока он уничтожает все ссылки созданные локальными переменными внутри него.
Вы всегда можете проверить количество ссылок используя функцию sys.getrefcount .
Пример работы счетчика ссылок:
foo = [] # 2 ссылки, одна от переменной foo и одна от getrefcount print(sys.getrefcount(foo)) def bar(a): # 4 ссылки # от foo, аргумента функции (a), getrefcount и одна от стека вызова функции print(sys.getrefcount(a)) bar(foo) # 2 ссылки, локальные ссылки внутри функции уничтожены print(sys.getrefcount(foo))
Основная причина, из-за которой стандартный интерпретатор (CPython) использует счетчик ссылок, является исторической. В настоящее время можно встретить множество дебатов по поводу данного подхода. Некоторые люди считают, что сборщик мусора может быть намного эффективней без участия алгоритма подсчета ссылок. У данного алгоритма есть множество проблем, таких как циклические ссылки, блокирование потоков, а также дополнительные накладные расходы на память и cpu.
Основным плюсом этого алгоритма является то, что объекты удаляются сразу как только они не нужны.
Дополнительный сборщик мусора
Зачем нам нужен дополнительный алгоритм, когда у нас уже есть подсчет ссылок?
К сожалению, классический алгоритм подсчета ссылок имеет один большой недостаток — он не умеет находить циклические ссылки. Циклические ссылки происходят когда один или более объектов ссылаются на друг друга.
Как вы можете видеть, объект lst ссылается сам на себя, тогда как object1 и object2 ссылаются друг на друга. Для таких объектов счетчик ссылок всегда будет равен 1.
Демонстрация на Python:
import gc # используется ctypes для доступа к объектам по адресу памяти class PyObject(ctypes.Structure): _fields_ = [(«refcnt», ctypes.c_long)] gc.disable() # выключаем циклический GC lst = [] lst.append(lst) # сохраняем адрес списка lst lst_address = id(lst) # удаляем ссылку lst del lst object_1 = <> object_2 = <> object_1[‘obj2’] = object_2 object_2[‘obj1’] = object_1 obj_address = id(object_1) # удаляем ссылки del object_1, object_2 # раскомментируйте для запуска ручной сборки объектов с циклическими ссылками # gc.collect() # проверяем счетчик ссылок print(PyObject.from_address(obj_address).refcnt) print(PyObject.from_address(lst_address).refcnt)
В примере выше, инструкция del удаляет ссылки на наши объекты (не сами объекты). Как только Python выполняет инструкцию del эти объекты становятся недоступны из Python кода. Однако, с выключенным модулем gc они по прежнему будут оставаться в памяти, т.к. они имели циклические ссылки и их счетчик по прежнему равен единице. Вы можете визуально исследовать такие связи используя библиотеку objgraph .
Для того, чтобы исправить эту проблему, в Python 1.5 был добавлен дополнительный алгоритм, известный как модуль gc. Единственная задача которого удаление циклических объектов, к которым уже нет доступа из кода.
Циклические ссылки могут происходить только в “контейнерных” объектах. Т.е. в объектах, которые могут хранить другие объекты, например в списках, словарях, классах и кортежах. GC не следит за простыми и неизменяемыми типами, за исключением кортежей. Некоторые кортежи и словари так же исключаются из списка слежки при выполнении определенных условий. Со всеми остальными объектами гарантированно справляется алгоритм подсчета ссылок.
Когда GC срабатывает
В отличие от алгоритма подсчета ссылок, циклический GC не работает в режиме реального времени и запускается периодически. Каждый запуск сборщика создаёт микропаузы в работе кода, поэтому CPython (стандартный интерпретатор) использует различные эвристики, для определения частоты запуска сборщика мусора.
Циклический сборщик мусора разделяет все объекты на 3 поколения (генерации). Новые объекты попадают в первое поколение. Если новый объект выживает процесс сборки мусора, то он перемещается в следующее поколение. Чем выше поколение, тем реже оно сканируется на мусор. Так-как новые объекты зачастую имеют очень маленький срок жизни (являются временными), то имеет смысл опрашивать их чаще, чем те, которые уже прошли через несколько этапов сборки мусора.
В каждой генерации есть специальный счетчик и порог срабатывания, при достижении которых срабатывает процесс сборки мусора. Каждый счетчик хранит количество аллокаций минус количество деаллокаций в данной генерации. Как только в Python создается какой либо контейнерный объект, он проверяет эти счетчики. Если условия срабатывают, то начинается процесс сборки мусора.
Если сразу несколько или больше поколений преодолели порог, то выбирается наиболее старшее поколение. Это сделано из-за того, что старые поколения также сканируют все предыдущие. Чтобы сократить число пауз сборки мусора для долгоживущих объектов, самая старшая генерация имеет дополнительный набор условий.
Стандартные пороги срабатывания для поколений установлены на 700, 10 и 10 соответственно, но вы всегда можете их изменить с помощью функций gc.get_threshold и gc.set_threshold .
Алгоритм поиска циклов
Для полноценного описания алгоритма поиска циклов потребуется отдельная статья. Если кратко, то GC итерирует каждый объект из выбранных поколений и временно удаляет все ссылки от отдельно взятого объекта (все ссылки на которые этот объект ссылается). После полного прохода, все объекты, у которых счетчик ссылок меньше двух считаются недоступными из питона и могут быть удалены.
Для более глубокого понимания я рекомендую прочитать (прим. переводчика: английский материал) оригинальное описание алгоритма от Neil Schemenauer и функцию collect из исходников CPython. Описание из Quora и пост о сборщике мусора так же могут быть полезны.
Стоит отметить, что проблема с деструкторами описанная в оригинальном описании алгоритма была исправлена начиная с Python 3.4 (подробнее в PEP 442).
Советы по оптимизации
Циклы зачастую случаются в реальных задачах, их можно встретить в задачах с графами, связными списками или в структурах данных, где требуется вести учёт отношений между объектами. Если ваша программа имеет высокую нагрузку и требовательна к задержкам, то, по возможности, циклы лучше избегать.
В местах, где вы заведомо используйте циклические ссылки, можно использовать «слабые» ссылки. Слабые ссылке реализованы в модуле weakref и в отличие от обычных ссылок никак не влияют на счётчик ссылок. Если объект со слабой ссылок оказывается удалённым, то вместо него возвращается None .
В некоторых случаях полезно отключить автоматическую сборку модулем gc и вызывать его вручную. Для этого достаточно вызывать gc.disable() и в дальнейшем вызывать gc.collect() вручную.
Как найти и отладить циклические ссылки
Отладка циклов может быть мучительной, особенно если в вашем коде используется множество сторонних модулей.
Модуль gc предоставляет вспомогательные функции, которые могут помочь в отладке. Если параметры GC установить на флаг DEBUG_SAVEALL , то все недоступные объекты будут добавлены в список gc.garbage .
import gc gc.set_debug(gc.DEBUG_SAVEALL) print(gc.get_count()) lst = [] lst.append(lst) list_id = id(lst) del lst gc.collect() for item in gc.garbage: print(item) assert list_id == id(item)
Как только вы определите проблемное место — его можно визуализировать с помощью objgraph.
Основной процесс сборки мусора выполняется алгоритмом подсчета ссылок, который очень простой и не имеет настроек. Дополнительный алгоритм используется только для поиска и удаления объектов с циклическими ссылками.
Не стоит заниматься преждевременной оптимизацией кода под сборщик мусора, на практике серьёзне проблемы со сборкой мусора встречаются довольно редко.
P.S.: Я являюсь автором этой статьи, можете задавать любые вопросы.
- Python
- Программирование
Источник: habr.com
Тема: [1.7.10] Thermal Expansion — завод пил
Nikitossss2
Просмотр профиля
Сообщения форума
Личное сообщение
Репутация
Узнаваемый
Ваш статус В игре
Сообщений 385
Cервер Новая сборка
Регистрация 25.12.2013
3 Прирост» убираем интегрированное серво (забирать итог будем сами поисковиком)
Над сборщиком ставим поисковик и ищем доски:
Вторая группа: резонирующая красная печь и основной циклический сборщик.
Над печью ставим резонирующий поисковик и ищим им булыгу:
Камень мы направляем вниз — в сборщик в котором делаем каменные палки:
Так же убираем расширение серво из вкладки Прирост.
Третья группа — два измельчителя (этих групп может быть несколько для увеличения производства кремня)
Настройка первого измельчителя и вкладка Прирост:
Настройка второго измельчителя и вкладка Прирост:
Из обоих мы сбоку уводим лишнее: песок (основной результат в первом измельчителе и доп продукт во втором).
Над первым измельчителем у нас как всегда поисковик ищущий в интерфейсе булыгу, настройки аналогично поисковику над красной печью.
Ставим ниже итоговый циклический сборщик, убираем из вкладки Прирост серво:
включаем красный контроль:
уводим итог нашей работы в интерфейс трубой слево (аналогично измельчителям):
Над ним у нас стоит поисковик, где выложены образцы каменной палки, кремня и простой палки. Обратите внимание на верхнюю цифру справа: «Увеличить максимальное количество предметов в инвентаре» — я поставил 128.
Теперь при производстве поисковик будет всегда поддерживать 2 стака фильтруемых предметов и не забивать сборщик.
Не забываем выставить белый список и игнор красного сигнала.
Ограничиваем производство — тянем к последнему сборщику мэ провод и ставим мэ излучатель уровня:
Теперь система сама будет поддерживать в мэ 1000 пил при наличии булыги и досок.
Таким образом, можно выстроить логическую систему сборки любого предмета (вспомним старый добрый завод сол панелей на RP2).
ПС — для желающих написать пост «в МЭ проще».
Да проще, но не всегда самый простой путь самый выгодный. Последнее время замечено конкретное отставание (проседание) мода АЕ от ТЕ и IC при большом количестве игроков. Поэтому и появилась идея разгрузить МЭ от лишних задачь.
Аналогично собираются и просто изолированные провода и сложные механизмы, было бы только желание.
Источник: minecraftonly.ru
Как улучшить приборы thermal expansion
Циклический сборщик (от англ. Cyclic Assembler) — устройство, добавляемое модификацией Thermal Expansion 2, использующие MJ-энергию для крафта предметов, используя рецепты крафта, хранящиеся на схемах. Потребляет 2 MJ/т, когда работает на максимальной скорости. Имеет буфер энергии равный 2400 MJ. На создание 1 предмета тратится 2 MJ.
Получение [ ]
Циклический сборщик можно мгновенно демонтировать с помощью серповидного молота. Его также можно добывать с помощью кирки, хотя это гораздо медленнее.
Крафт [ ]
Интерфейс [ ]
Ввод и вывод [ ]
Предметы и жидкости могут входить в циклический сборщик, предметы выходить из него через его стенки. Каждая сторона циклического сборщика может соответствовать входному слоту, одному из выходных слотов или определённым слотам одновременно.
Циклический сборщик может автоматически перемещать предметы с любых сторон, которые непосредственно соответствуют одному из его выходных слотов. Это называется автоматическим выводом. Автоматический вывод происходит всякий раз, когда машина заканчивает обработку предмета, или каждые 32 тика (1,6 секунды), если машина неактивна. Циклический сборщик может автоматически передавать до 8 предметов за раз. Каждую сторону можно настроить на соответствие определёнными слотам с помощью вкладки «Конфигурация» в графическом интерфейсе.
Управление [ ]
Циклический сборщик может быть настроен на управление по сигналу красного камня. Это может быть один из трех режимов:
Управление сигналом красного камня отключено. Циклический сборщик работает по возможности.
Циклический сборщик работает без питания. При питании перестает работать. Это режим «по умолчанию».
Циклический сборщик работает только при включенном питании. Текущий режим можно установить с помощью вкладки «Контроль» в графическом интерфейсе.
Указание рецепта [ ]
Для указания рецепта сначала нужно положить схему в слот для схем. После этого нужно открыть вкладку «Схема». Указав нужный рецепт, нужно кликнуть на «галочку». После этого рецепт запишется на схему. И механизм готов к работе.
Для использования жидкостей в рецепте, можно указать контейнер, с определённой жидкостью, при этом сами контейнеры для создания могут не использоваться, в таком случае нужная для создания жидкость должна быть залита в бак.
Использование [ ]
Размещение [ ]
При установке циклический сборщик обращен к игроку. Он может быть обращён в любую из четырёх сторон света и может вращаться с помощью серповидного молота.
Обработка [ ]
Для создания предметов циклический сборщик должен быть настроен на выполнение определённого рецепта крафта. Когда необходимые предметы для настроенного рецепта помещаются в слоты для ввода, машина начнёт потреблять энергию для изготовления указанных предметов, также предметы и жидкости, используемые в рецепте сразу потребляются. При потреблении достаточного количества энергии вывод помещается в выходной слот. Если рецепт производит остатки предметов, например три пустых ведра при создании торта, эти предметы помещаются обратно в входные слоты машины.
Thermal Expansion 1/Измельчитель
Работает: да, 4
Простаивает: нет
Измельчитель (от англ. Pulverizer) — устройство, добавляемое модификацией Thermal Expansion 1, использующие MJ-энергию для измельчения и переработки определённых предметов. Поддерживает медь, олово и серебро из других модов.
Получение [ ]
Измельчитель можно мгновенно демонтировать с помощью серповидного молота. Его также можно добывать с помощью кирки, хотя это гораздо медленнее.
Крафт [ ]
Интерфейс [ ]
Синий | Используется для ввода ингредиентов. |
Красный | Используется для вывода основного продукта. |
Жёлтый | Используется для вывода побочного продукта. |
Оранжевый | Используется для вывода основного и побочного продукта. |
Бесцветный | Используется для автономного питания механизма. |
Ввод и вывод [ ]
Предметы могут входить в измельчитель и выходить из него через его стенки. Каждая сторона измельчителя может соответствовать входному слоту, одному из выходных слотов или определённым слотам одновременно.
Измельчитель может автоматически перемещать предметы с любых сторон, которые непосредственно соответствуют одному из его выходных слотов. Вывод измельчённых предметов происходит всякий раз, когда машина заканчивает обработку предмета, или каждые 32 тика (1,6 секунды), если машина простаивает. Измельчитель может автоматически передавать до 8 предметов за раз. Каждую сторону можно настроить на соответствие определёнными слотам с помощью вкладки «Конфигурация» в графическом интерфейсе.
Управление [ ]
Измельчитель может быть настроен на управление по сигналу красного камня. Это может быть один из трёх режимов:
- Отключён
Управление сигналом красного камня отключено. Измельчитель работает по возможности. - Низкий
Измельчитель работает без сигнала. При подаче сигнала перестаёт работать. Этот режим установлен «по умолчанию». - Высокий
Измельчитель работает только при подаче сигнала.
Текущий режим можно установить с помощью вкладки «Контроль» в графическом интерфейсе.
Использование [ ]
Размещение [ ]
При установке измельчитель обращен к игроку. Он может быть обращен в любую из четырёх сторон света и может вращаться с помощью серповидного молота.
Обработка [ ]
Когда предметы помещаются во входной слот измельчителя, машина начинает использовать MJ-энергию для их обработки. Для обработки каждого предмета требуется определённое количество энергии. Если в механизме есть немного энергии, то предмет сразу потребляется, и его уже нельзя извлечь.
Когда для предмета израсходовано достаточно энергии результат помещается в слот основного вывода. Вторичный вывод может быть произведён при обработке определённых предметов. Скорость, с которой работает измельчитель, зависит от того, сколько энергии он может использовать за такт. Это в свою очередь зависит от того, сколько энергии запасено в механизме.
Потребляет 4 MJ/т, когда работает на максимальной скорости. Имеет энерго-буфер равный 4800 MJ.
Thermal Expansion 5
Java Edition |
Команда разработчиков TeamCoFH |
20 июня 2017 г. |
1.12.2 5.5.7.1 1.11.2 5.2.7.30 1.10.2 5.1.10.28 |
См. Установка |
Minecraft Forge, CoFH Core, CodeChickenLib, Thermal Foundation 2 |
Thermal Expansion 5— это модификация для Minecraft 1.10.2, 1.11.2, 1.12, 1.12.1, а также 1.12.2. Она добавляет в игру новую механику обработки ресурсов, организацию автоматического производства, новые ресурсы, их обработчики, а также энергию и устройства её выработки и хранения. Является частью Thermal Series.
Начиная с версии 5.0.0 модификация была очень сильно изменена, в частности была добавлена новая система обновлений механизмов, и переработана система расширений.
Механизмы
Механизмы
Все механизмы требуют энергию и моментально демонтируется серповидным молотом с сохранением энергии.
Поддерживают расширения для механизмов.
Механизмы можно обновить до более высокого уровня. Это повлияет на:
Thermal Expansion 2/Вулканический пресс
Активен: да, 14
Простаивает: нет
Вулканический пресс (от англ. Igneous Extruder) — устройство, добавляемое модификацией Thermal Expansion 2, использующие воду и лаву для создания булыжника, камня, обсидиана. Не требует энергию для своей работы.
Получение [ ]
Вулканический пресс можно мгновенно демонтировать с помощью серповидного молота. Его также можно добывать с помощью кирки, хотя это гораздо медленнее.
Крафт [ ]
Интерфейс [ ]
Синий | Используется для импорта жидкости. |
Красный | Используется для выбора продукта. |
Оранжевый | Используется для экспорта готового продукта. |
Ввод и вывод [ ]
Предметы могут выходить из вулканического пресса через его стенки. Каждая сторона вулканического пресса может соответствовать входному или выходному слоту.
Вулканический пресс может автоматически перемещать предметы с любых сторон, которые непосредственно соответствуют одному из его выходных слотов. Это называется автоматическим выводом. Автоматический вывод происходит всякий раз, когда машина заканчивает обработку предмета, или каждые 32 тика (1,6 секунды), если машина неактивна. Вулканический пресс может автоматически передавать до 8 предметов за раз. Каждую сторону можно настроить на соответствие определёнными слотам с помощью вкладки «Конфигурация» в графическом интерфейсе.
Управление [ ]
Вулканический пресс может быть настроен на управление по сигналу красного камня. Это может быть один из трех режимов:
Управление сигналом красного камня отключено. Вулканический пресс работает по возможности.
Вулканический пресс работает без питания. При питании перестает работать. Это режим «по умолчанию».
Вулканический пресс работает только при включенном питании. Текущий режим можно установить с помощью вкладки «Контроль» в графическом интерфейсе.
Использование [ ]
Размещение [ ]
При установке вулканический пресс обращён к игроку. Он может быть обращён в любую из четырёх сторон света и может вращаться с помощью серповидного молота.
Источник: akter-sochi.ru