Как зайти в Даркнет?!
25th January, 01:11
8
0
Как в tkinter из поля ввода Entry получить значение в одну переменную и обновить строку кнопкой, затем получить ещё одно введённое значение и затем сложить их. Ниже пример кода
21st July, 19:00
899
0
Программа, которая создает фейковые сервера в поиске игровых серверов CS 1.6 Steam
21st March, 17:43
952
0
Очень долго работает Update запрос Oracle
27th January, 09:58
916
0
не могу запустить сервер на tomcat HTTP Status 404 – Not Found
21st January, 18:02
907
0
Где можно найти фрилансера для выполнения поступающих задач, на постоянной основе?
2nd December, 09:48
942
0
Разработка мобильной кроссплатформенной военной игры
16th July, 17:57
1727
0
период по дням
25th October, 10:44
3957
0
Пишу скрипты для BAS только на запросах
16th September, 02:42
3722
0
Некорректный скрипт для закрытия блока
14th April, 18:33
4614
0
прокидывать exception в блоках try-catch JAVA
11th March, 21:11
4382
0
Помогите пожалуйста решить задачи
24th November, 23:53
6087
0
Не понимаю почему не открывается детальное описание продукта
11th November, 11:51
4352
0
Нужно решить задачу по программированию на массивы
27th October, 18:01
4400
0
Метода Крамера С++
23rd October, 11:55
4309
0
помогите решить задачу на C++
22nd October, 17:31
4002
0
Помогите решить задачу на python с codeforces
22nd October, 11:11
4492
0
Python с нуля: полное руководство для начинающих
18th June, 13:58
2599
0
Почему Java и Python методы сбора мусора отличаются?
Python использует метод подсчета ссылок для обработки времени жизни объекта. Таким образом, объект, который больше не имеет смысла, будет немедленно уничтожен.
Но в Java GC (сборщик мусора) уничтожает объекты, которые больше не используются в определенное время.
Почему Java выбирает именно эту стратегию и в чем ее польза?
Это лучше, чем подход Python?
Есть и недостатки использования отсчета ссылок. Один из наиболее упоминаемых-циклические ссылки: предположим, что A ссылается на B, B ссылается на C и C ссылки B. Если A отбросит свою ссылку на B, то и B, и C все равно будут иметь количество ссылок 1 и не будут удалены при традиционном подсчете ссылок. CPython (подсчет ссылок не является частью самого python, но частью его реализации C) улавливает циклические ссылки с помощью отдельной процедуры сборки мусора, которая периодически выполняется...
Еще один недостаток: подсчет ссылок может замедлить выполнение. Каждый раз, когда на объект ссылаются и разыменовывают его, интерпретатор/VM должен проверить, снизился ли счетчик до 0 (и затем освободить его, если это произошло). Сборщик мусора не нуждается в этом.
Кроме того, сбор мусора может быть выполнен в отдельном потоке (хотя это может быть немного сложно). На машинах с большим количеством RAM и для процессов, которые используют память только медленно, вы можете вообще не делать GC! Подсчет ссылок был бы здесь небольшим недостатком с точки зрения производительности...
На самом деле подсчет ссылок и стратегии, используемые Sun JVM, - это разные типы алгоритмов сбора мусора.
Существует два широких подхода к отслеживанию мертвых объектов: отслеживание и подсчет ссылок. В трассировке GC начинается с "roots"-вещей, таких как ссылки стека, и отслеживает все доступные (живые) объекты. Все, что не может быть достигнуто, считается мертвым. При подсчете ссылок каждый раз, когда ссылка изменяется, участвующие объекты обновляют свой счетчик. Любой объект, чей счетчик ссылок становится равным нулю, считается мертвым.
В основном во всех реализациях GC есть компромиссы, но трассировка обычно хороша для высокой сквозной операции put (т. е. быстрой), но имеет более длительное время паузы (большие промежутки, когда UI или программа могут замерзнуть). Подсчет ссылок может работать в меньших кусках, но в целом будет медленнее. Это может означать меньше замораживаний, но в целом худшую производительность.
Кроме того, отсчет ссылок GC требует наличия детектора циклов для очистки любых объектов в цикле, которые не будут пойманы только их отсчетом ссылок. Perl 5 не имел детектора циклов в своей реализации GC и мог пропускать память, которая была циклической.
Исследования также были сделаны, чтобы получить лучшее из обоих миров (низкое время паузы, высокая пропускная способность): http://cs.anu.edu.au/~Steve.Blackburn/pubs/papers/urc-oopsla-2003.pdf
Даррен Томас дает хороший ответ. Однако одно большое различие между подходами Java и Python заключается в том, что при подсчете ссылок в общем случае (без циклических ссылок) объекты очищаются немедленно, а не в какой-то неопределенный более поздний срок.
Например, я могу написать небрежный, непереносимый код в CPython, например
def parse_some_attrs(fname):
return open(fname).read().split("~~~")[2:4]
и файловый дескриптор для этого файла, который я открыл, будет немедленно очищен, потому что как только ссылка на открытый файл исчезнет, файл будет собран мусором и файловый дескриптор будет освобожден. Конечно, если я запущу Jython или IronPython или, возможно, PyPy, то сборщик мусора не обязательно будет работать намного позже; возможно, у меня сначала закончатся файловые дескрипторы, и моя программа рухнет.
Итак, вы SHOULD будете писать код, который выглядит так
def parse_some_attrs(fname):
with open(fname) as f:
return f.read().split("~~~")[2:4]
но иногда людям нравится полагаться на подсчет ссылок, чтобы всегда освободить свои ресурсы, потому что это иногда может сделать ваш код немного короче.
Я бы сказал, что лучший сборщик мусора-это тот, у которого лучшая производительность, который в настоящее время кажется поколенческим сборщиком мусора в стиле Java, который может работать в отдельном потоке и имеет все эти сумасшедшие оптимизации и т. д. Различия в том, как вы пишете свой код, должны быть незначительными и в идеале отсутствовать.
Я думаю, что статья "теория и практика Java: Краткая история сбора мусора" от IBM должна помочь объяснить некоторые из ваших вопросов.
Сбор мусора выполняется быстрее (более эффективно по времени), чем подсчет ссылок, если у вас достаточно памяти. Например, копирующий gc обходит объекты "live" и копирует их в новое пространство, а также может восстановить все объекты "dead" за один шаг, отметив всю область памяти. Это очень эффективно, если у вас достаточно памяти. Коллекции поколений используют знание о том, что" большинство объектов умирают молодыми"; часто только несколько процентов объектов приходится копировать.
[Это также причина, по которой gc может быть быстрее, чем malloc/free]
Подсчет ссылок гораздо более эффективен, чем сбор мусора, поскольку он восстанавливает память в тот самый момент, когда она становится недоступной. Это удобно, когда вы хотите прикрепить финализаторы к объектам (например, чтобы закрыть файл, как только файловый объект становится недостижимым). Система подсчета ссылок может работать даже тогда, когда только несколько процентов памяти свободны. Но затраты на управление приращением и уменьшением счетчиков при каждом назначении указателя стоят много времени, и для восстановления циклов все еще требуется некоторая сборка мусора.
Таким образом, компромисс очевиден: если вы должны работать в среде с ограниченным объемом памяти или если вам нужны точные финализаторы, используйте подсчет ссылок. Если у вас достаточно памяти и нужна скорость, используйте сбор мусора.
Одним из больших недостатков трассировки Java GC является то, что время от времени она будет "stop the world" и замораживать приложение на относительно долгое время, чтобы сделать полный GC. Если куча большая, а дерево объектов сложное, то она замерзнет на несколько секунд. Кроме того, каждый полный GC посещает все дерево объектов снова и снова, что, вероятно, довольно неэффективно. Еще одним недостатком способа Java делает GC является то, что вы должны сказать jvm, какой размер кучи вы хотите (если значение по умолчанию недостаточно хорошо); JVM выводит из этого значения несколько пороговых значений, которые вызовут процесс GC, когда в куче накопится слишком много мусора.
Я предполагаю, что это на самом деле является основной причиной резкого ощущения Android (на основе Java), даже на самых дорогих мобильных телефонах, по сравнению с гладкостью iOS (на основе ObjectiveC и с использованием RC).
Я хотел бы видеть опцию jvm, чтобы включить управление памятью RC, и, возможно, сохранить GC только для запуска в крайнем случае, когда больше не останется памяти.
Последние Sun Java VM на самом деле имеют несколько алгоритмов GC, которые вы можете настроить. В спецификациях Java VM намеренно опущено указание фактического поведения GC, чтобы разрешить различные (и множественные) алгоритмы GC для различных VMs.
Например, для всех людей, которым не нравится подход" stop-the-world " к поведению Sun Java VM GC по умолчанию, есть VM, такие как IBM в режиме реального времени , который позволяет приложению реального времени работать на Java.
Поскольку спецификация Java VM является общедоступной, нет (теоретически) ничего, что помешало бы кому-либо реализовать Java VM, который использует алгоритм CPython GC.
Подсчет ссылок особенно трудно эффективно выполнять в многопоточной среде. Я не знаю, как бы вы даже начали это делать, не попадая в аппаратные транзакции или подобные (в настоящее время) необычные атомарные инструкции.
Подсчет ссылок легко осуществить. JVMs вложили много денег в конкурирующие реализации, поэтому неудивительно, что они реализуют очень хорошие решения очень сложных проблем. Тем не менее, становится все более легко нацелить свой любимый язык на JVM.
В конце игры, но я думаю, что одним из важных обоснований для RC в python является его простота. Смотрите , например, этот email от Алекса Мартелли.
(Я не смог найти ссылку за пределами кэша google, дата email от 13 октября 2005 года в списке python).