Почему Java и методы сборки "мусора" Python отличаются?

Вам нужно получить положение мыши относительно холста

. Для этого вам нужно знать положение X / Y холста на странице.

Это называется «смещением» холста, и вот как получить смещение. (Я использую jQuery, чтобы упростить кросс-браузерную совместимость, но если вы хотите использовать сырой javascript, то быстрый Google тоже получит это.)

    var canvasOffset=$("#canvas").offset();
    var offsetX=canvasOffset.left;
    var offsetY=canvasOffset.top;

Затем в обработчике мыши вы можете получим мышь X / Y следующим образом:

  function handleMouseDown(e){
      mouseX=parseInt(e.clientX-offsetX);
      mouseY=parseInt(e.clientY-offsetY);
}

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

http: //jsfiddle.net/m1erickson/WB7Zu/




 









    

Move, press and release the mouse

Down

Move

Up

Out

51
задан erikreed 10 March 2013 в 12:27
поделиться

8 ответов

Существуют недостатки использования подсчета ссылок. Один из наиболее упомянутых является циклическими ссылками: Предположим ссылки B, B ссылки C и ссылки C B. Если A должны были отбросить его ссылку на B, и B и C будут все еще иметь подсчет ссылок 1 и не будут удалены с традиционным подсчетом ссылок. CPython (подсчет ссылок не является частью самого Python, но частью реализации C этого) ловит циклические ссылки с отдельной стандартной программой сборки "мусора", которую это периодически выполняет...

Другой недостаток: Подсчет ссылок может сделать выполнение медленнее. Каждый раз, когда на объект ссылаются и разыменовывают, interpreter/VM должен проверить, чтобы видеть, снизилось ли количество 0 (и затем освободите, если это сделало). Сборка "мусора" не должна делать этого.

кроме того, Сборка "мусора" может быть сделана в отдельном потоке (хотя это может быть немного хитро). На машинах с большим количеством RAM и для процессов, которые используют память только медленно, Вы не могли бы хотеть делать GC вообще! Подсчет ссылок был бы определенным недостатком там с точки зрения производительности...

46
ответ дан Daren Thomas 7 November 2019 в 10:02
поделиться

На самом деле подсчет ссылок и стратегии, используемые JVM Sun, являются всеми различными типами алгоритмов сборки "мусора".

существует два широких подхода для того, чтобы разыскать мертвые объекты: трассировка и подсчет ссылок. В трассировке GC начинает с "корней" - вещи как ссылки стека и прослеживает все достижимые (живые) объекты. Что-либо, что не может быть достигнуто, считают мертвым. В подсчете ссылок каждый раз, когда ссылка изменяется, объект включил, обновили их количество. Любой объект, подсчет ссылок которого обнуляется, считают мертвым.

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

Дополнительно GC подсчета ссылок требует, чтобы детектор цикла очистил любые объекты в цикле, который не будет пойман одним только их подсчетом ссылок. Perl 5 не имел детектора цикла в своей реализации GC и мог пропустить память, которая была циклической.

Исследование было также проведено для получения лучшего из обоих миров (низкие времена паузы, высокая пропускная способность): http://cs.anu.edu.au/~Steve.Blackburn/pubs/papers/urc-oopsla-2003.pdf

27
ответ дан Luke Quinane 7 November 2019 в 10:02
поделиться

Darren Thomas дает хороший ответ. Однако одна большая разница между Java и подходами Python - то, что с подсчетом ссылок в общем падеже (никакие циклические ссылки) объекты сразу очищены, а не в некоторую неопределенную более позднюю дату.

, Например, я могу записать неаккуратный, непортативный код в CPython такой как

def parse_some_attrs(fname):
    return open(fname).read().split("~~~")[2:4]

и дескриптор файла для того файла, который я открыл, будет сразу очищен, потому что, как только ссылка на открытый файл уходит, файл собран "мусор", и дескриптор файла освобожден. Конечно, если я выполню Jython или IronPython или возможно PyPy, тогда сборщик "мусора" будет не обязательно значительно позже работать; возможно у меня закончатся дескрипторы файлов сначала, и моя программа откажет.

, Таким образом, НЕОБХОДИМО писать код, который похож

def parse_some_attrs(fname):
    with open(fname) as f:
        return f.read().split("~~~")[2:4]

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

я сказал бы, что лучший сборщик "мусора" является тем с лучшей производительностью, которая в настоящее время, кажется, стиль Java сборщики "мусора" поколений, которые могут работать в отдельном потоке и имеют всю эту сумасшедшую оптимизацию и т.д. Различия к тому, как Вы пишете свой код, должны быть незначительными и идеально не существовать.

15
ответ дан Eli Courtwright 7 November 2019 в 10:02
поделиться

Я думаю статья" теория Java и практика: краткая история сборки "мусора" " от IBM должна помочь объяснить некоторые вопросы, которые Вы имеете.

8
ответ дан Espo 7 November 2019 в 10:02
поделиться

Сборка "мусора" быстрее (больше эффективного времени), чем подсчет ссылок, если у Вас есть достаточно памяти. Например, gc копирования пересекает "живые" объекты и копирует их в новое пространство и может исправить все "мертвые" объекты за один шаг путем маркировки целого региона памяти. Это очень эффективно, , если у Вас есть достаточно памяти. Наборы поколений используют знание, что "большинство объектов умирает молодое"; часто только несколько процентов объектов должны быть скопированы.

[Это - также причина, почему gc может быть быстрее, чем malloc/free]

, Подсчет ссылок является намного большим количеством пространства, эффективного, чем сборка "мусора", так как это исправляет память самый момент, это становится недостижимым. Это хорошо, когда Вы хотите присоединить финализаторы к объектам (например, закрыть файл, как только объект Файла становится недостижимым). Система подсчета ссылок может работать, даже когда только несколько процентов памяти свободны. Но стоимость управления необходимости увеличить и постепенно уменьшить счетчики на каждое присвоение указателя стоила большого количества времени, и некоторая сборка "мусора" все еще необходима для исправления циклов.

, Таким образом, компромисс ясен: если необходимо работать в ограниченной памятью среде, или если Вам нужны точные финализаторы, используйте подсчет ссылок. Если Вы имеете достаточно памяти и нуждаетесь в скорости, используйте сборку "мусора".

5
ответ дан mfx 7 November 2019 в 10:02
поделиться

Последние VM Java Sun на самом деле имеют несколько алгоритмов GC, которые можно настроить. Java спецификации VM намеренно опустил определять фактическое поведение GC позволить отличающийся (и несколько) алгоритмы GC для различного VMs.

, Например, для всех людей, которым не нравится "stop-world" подход Java Sun по умолчанию поведение GC VM, существуют VM такой как Реальное время WebSphere IBM , который позволяет приложению реального времени работать на Java.

Начиная с Java спецификация VM общедоступна, нет (теоретически) ничего мешающего никому реализовать Java VM, который использует алгоритм GC CPYTHON.

2
ответ дан ckpwong 7 November 2019 в 10:02
поделиться

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

Подсчет ссылок легко реализовать. JVMs имели много денег, сниженных в конкурирующие реализации, таким образом, не должно быть удивительно, что они реализуют очень хорошие решения очень трудных проблем. Однако становится все больше легко предназначаться для Вашего любимого языка в JVM.

2
ответ дан Tom Hawtin - tackline 7 November 2019 в 10:02
поделиться

Поздно в игре, но я думаю, что одним из важных аргументов в пользу RC в Python является его простота. См., Например, это электронное письмо Алекса Мартелли .

(я не смог найти ссылку вне кеша Google, дата электронного письма от 13 октября 2005 г. в списке Python).

0
ответ дан 7 November 2019 в 10:02
поделиться
Другие вопросы по тегам:

Похожие вопросы: