Подтвердить что ты не робот

Виртуальная виртуальная машина Java перемещает объекты в памяти, и если да - как?

Виртуальная машина Java когда-либо перемещает объекты в памяти, и если да, то как она обрабатывает ссылки на перемещенный объект?

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

Мои две идеи до сих пор:

  • Поддерживайте ссылочное обозначение где-то, что не движется за время жизни объекта, которое мы обновляем, если объект перемещается. Но как справиться с этими отказами?
  • Сохраняйте список обратных ссылок с каждым объектом, поэтому мы знаем, что нужно обновлять, если объект перемещен. Конечно, это создает накладные расходы.

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

4b9b3361

Ответ 1

В связи с комментарием выше о ходьбе кучи.

Различные GC делают это по-разному.

Обычно копирующие коллекторы, когда они ходят в кучу, не перемещают все объекты в куче. Скорее они ходят объекты LIVE в кучу. Импликация заключается в том, что, если она достижима из "корневого" объекта, объект жив.

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

Двумя основными преимуществами такого коллекционера являются то, что он уплотняет кучу во время фазы копирования и копирует только живые объекты. Это важно для многих систем, потому что с таким видом коллектора распределение объектов грязно дешево, буквально немного больше, чем приращение указателя кучи. Когда GC происходит, ни один из "мертвых" объектов не копируется, поэтому они не замедляют сборщик. В динамических системах также оказывается, что там намного меньше, временный мусор, чем есть многолетний мусор.

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

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

Генерирующий копирующий GC будет помещать "старые" объекты в разные кучи, а те, которые собираются реже, чем "новые" кучи. Теория состоит в том, что долговечные объекты получают более старшие поколения и собираются все меньше и меньше, улучшая общую производительность GC.

Ответ 2

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

То, что вы смотрите, - очень большой и сложный вопрос. Я бы посоветовал вам ознакомиться с существующими API-интерфейсами удаленных объектов: удалением .NET и последующими технологиями, такими как CORBA

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

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

Ответ на комментарии:

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

Я не слишком разбираюсь в деталях сборщика мусора Java, и я уверен, что сборщики мусора Java и .NET имеют большую сложность для достижения максимальной производительности с минимальным воздействием на приложение.

Однако основная идея сбора мусора:

  • VM останавливает выполнение всех потоков из управляемого кода
  • Он выполняет анализ достижимости из набора известных "корней": статические переменные, локальные переменные во всех потоках. Для каждого объекта он находит, что он следует за всеми ссылками внутри объекта.
  • Любой объект, не идентифицированный анализом достижимости, является мусором.
  • Объекты, которые все еще живы, могут быть перенесены в память, чтобы их плотно упаковать. Это означает, что любые ссылки на эти объекты также должны быть обновлены с новым адресом. Контролируя, когда может произойти сбор мусора, ВМ может гарантировать, что нет ссылок на объекты "в воздухе" (т.е. Удерживается в машинном регистре), что может вызвать проблему.
  • Как только процесс будет завершен, виртуальная машина снова запустит выполнение потоков.

В качестве уточнения этого процесса VM может выполнять сборку мусора для генерации, где отдельные кучи поддерживаются на основе "возраста" объекта. Объекты начинаются в куче 0, и если они выживают в нескольких GC, то мигрируют в кучу 1 и, в конце концов, в кучу 2 (и так далее -.NET поддерживает только 3 поколения). Преимущество этого состоит в том, что GC может очень часто запускать сборники кучи 0, и не нужно беспокоиться о том, чтобы выполнить работу, чтобы доказать, что долгоживущие объекты (которые оказались в куче 2) все еще живы (что они почти наверняка есть).

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

Ответ 3

Мне было бы интересно узнать больше о ваших требованиях. Как еще один ответ, Terracotta может быть именно тем, что вы ищете.

Между тем, что предлагает Terracotta, и тем, что вы просите, существует тонкая разница, поэтому мой запрос.

Различие заключается в том, что Terracotta не предоставляет "remote" ссылок на объекты - фактически все понятие "remote" RMI, JMS и т.д. полностью отсутствует при использовании Terracotta.

Скорее, в Terracotta все объекты находятся в большой виртуальной куче. Темы, будь то в Node 1 или Node 2, Node 3, Node 4 и т.д., Все имеют доступ к любому объекту в виртуальной куче.

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

Короче говоря, то, что предлагает Terracotta, является моделью программирования для нескольких JVM, которые работают точно так же, как модель программирования для одной JVM. Нити в отдельных узлах просто ведут себя как потоки в одной мутации Node - объекта, синхронизируются, ожидают, уведомляют, что все ведут себя точно так же на узлах, как и в потоках - нет разницы.

Кроме того, в отличие от любого решения перед ним, ссылки на объекты поддерживаются через узлы - это означает, что вы можете использовать ==. Все это часть поддержки модели памяти Java в кластере, которая является основным требованием для создания "обычной" Java (например, POJO, synchronized, wait/notify) (ничто из этого не работает, если вы не можете/не можете сохранить объекта через кластер).

Итак, вопрос вернется к вам для дальнейшего уточнения ваших требований - для чего вам нужны указатели "remote"?

Ответ 4

Ключевое слово, которое вы используете, - это "уплотнение сборщика мусора". JVM разрешено использовать один, что означает, что объекты могут быть перемещены. Обратитесь к руководству JVM, чтобы узнать, есть ли у вас, и чтобы увидеть, есть ли какие-либо параметры командной строки, которые влияют на него.

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

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

Ответ 5

звучит так, как будто вы ищете распределенный кеш, что-то вроде терракотового или oracle java objece cache (ранее tangersol).

Ответ 6

Если вы захотите пойти вглубь, вы можете взглянуть на документы архитектуры JBoss Cache и получить часть своего исходного кода в качестве ссылки.

Это не совсем то, что вы описали, но оно очень похоже.

Здесь ссылка.

http://www.jboss.org/jbosscache/

Надеюсь, это поможет.