Как отметил @FelixKling, наиболее вероятным сценарием является то, что узлы, которые вы ищете, еще не существуют.
Однако современные методы разработки часто могут манипулировать элементами документа за пределами дерева документов либо с DocumentFragments, либо просто отсоединением / повторным подключением текущих элементов напрямую. Такие методы могут использоваться как часть шаблонов JavaScript или для предотвращения чрезмерных операций перерисовки / переплавки, в то время как элементы, о которых идет речь, сильно изменяются.
Аналогично, новая функциональность «Теневой DOM» развертывается в современных браузерах позволяет элементам быть частью документа, но не обрабатываться запросом document.getElementById и всеми его методами sibling (querySelector и т. д.). Это делается для инкапсуляции функциональных возможностей и, в частности, скрыть его.
Опять же, скорее всего, элемент, который вы ищете, просто (пока) в документе, и вы должны сделать, как предлагает Феликс , Тем не менее, вы также должны знать, что это все чаще является не единственной причиной того, что элемент может быть необоснованным (временно или постоянно).
Если быть точным, сборщики мусора являются проблемой для систем реального времени. Чтобы быть еще более точным, можно писать программное обеспечение в реальном времени на языках, которые имеют автоматическое управление памятью.
Более подробную информацию можно найти в Спецификации реального времени для Java об одном из подходов для достижения поведения в реальном времени с использованием Java. Идея RTSJ очень проста - не использовать кучу. RTSJ предоставляет новые разновидности объектов Runnable, которые гарантируют, что потоки не получат доступ к памяти кучи любого вида. Потоки могут получать доступ к памяти с областью действия (ничего необычного; значения уничтожаются при закрытии области действия) или к бессмертной памяти (которая существует в течение всего времени жизни приложения). Переменные в бессмертной памяти записываются снова и снова с новыми значениями.
Благодаря использованию бессмертной памяти RTSJ гарантирует, что потоки не обращаются к куче, и что более важно, система не имеет сборщика мусора, который препятствует выполнению программы потоками.
Более подробная информация доступна в статье «Проект Золотые Ворота: на пути к Java в реальном времени в космических полетах», опубликованной JPL и Sun .
Это потенциальная проблема, НО ...
Ваш персонаж может также зависнуть в середине вашей программы на C ++, пока ОС извлекает страницу памяти с перегруженного жесткого диска. Если вы не используете ОС реального времени на оборудовании, предназначенном для обеспечения конкретных гарантий производительности, вам никогда не гарантируется производительность.
Чтобы получить более конкретный ответ, вам нужно спросить о конкретной реализации конкретной виртуальной машины. Вы можете использовать виртуальную машину со сборщиком мусора для систем реального времени, если она обеспечивает подходящие гарантии производительности для сборки мусора.
Наша компания использует большое программное приложение на основе .Net, которое, помимо прочего, контролирует двоичные датчики в сетях полевой шины. В некоторых ситуациях датчики активируются только на короткое время (300 мс), но нашему программному обеспечению все еще необходимо фиксировать эти события, так как контролируемая система сразу же потерпит неудачу, если событие пропущено. Недавно мы наблюдали увеличение проблем на сайтах наших клиентов из-за сборщика мусора, работающего в течение длительного времени (до 1 секунды). Мы все еще пытаемся выяснить, как установить ограничение времени для сборщика мусора. В заключение этого короткого рассказа я бы сказал, что сборщик мусора является недостатком в приложениях, критичных ко времени.
Да, мусор должен обрабатываться детерминистическим образом в системах реального времени.
Один из подходов заключается в планировании определенного количества времени для сборки мусора во время каждого выделения памяти. Это называется «сборка мусора на основе работы». Идея заключается в том, что при отсутствии утечек распределение и сбор должны быть пропорциональными.
Другой простой подход («сборка мусора на основе времени») заключается в планировании определенной доли времени для периодической сборки мусора, независимо от того, нужна она или нет.
В любом случае возможно, что программе не хватит используемой памяти, поскольку ей не разрешается тратить достаточно времени на полную сборку мусора. Это отличается от системы не в реальном времени, которой разрешено приостанавливать столько времени, сколько необходимо для сбора мусора.
Я писал игры на Java и .NET и никогда не считал это большой проблемой. Я полагаю, что ваши «страшилки» основаны на сборщиках мусора много лет назад - с тех пор технология действительно продвинулась далеко вперед.
Единственное, для чего я не решился бы использовать Java / .NET на основе сборки мусора, это что-то вроде встроенного программирования с жесткими ограничениями в реальном времени (например, контроллеры движения).
Однако вам нужно знать о паузах GC, и все следующее может быть полезным для минимизации риска пауз GC:
Если вы очень богаты, вы, конечно, можете купить машины с аппаратной поддержкой GC . : -)
С теоретической точки зрения сборщики мусора — это не проблема, а решение. Системы реального времени сложны, когда есть динамическое выделение памяти. В частности, обычные функции C malloc()
и free()
не дают гарантий реального времени (обычно они работают быстро, но имеют, по крайней мере теоретически, «наихудшие случаи», когда они используют чрезмерное количество времени).
Так случилось, что можно создать динамический распределитель памяти, который предлагает гарантии в реальном времени, но это требует от распределителя выполнения некоторых сложных действий, в частности перемещения некоторых объектов в ОЗУ. Перемещение объекта подразумевает корректировку указателей (прозрачно, с точки зрения кода приложения), и в этот момент распределитель находится всего в одном шаге от того, чтобы стать сборщиком мусора.
Обычные реализации Java или .NET не предлагают сборку мусора в реальном времени в смысле гарантированного времени отклика, но их сборщик мусора по-прежнему сильно оптимизирован и в большинстве случаев имеет очень короткое время отклика. В нормальных условиях очень короткое среднее время отклика лучше, чем гарантированное время отклика («гарантированное» не означает «быстрое»).
Также обратите внимание, что обычные реализации Java или .NET работают в операционных системах, которые также не работают в режиме реального времени (ОС может решить запланировать другие потоки или может агрессивно отправить некоторые данные в файл подкачки и т. д.). как и базовое оборудование (например, типичный жесткий диск может время от времени делать «паузы перекалибровки»).Если вы готовы терпеть случайные временные сбои из-за аппаратного обеспечения, то вам подойдет (тщательно настроенный) сборщик мусора JVM. Даже для игр.