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

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

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

На данный момент у меня есть две идеи:

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

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

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
15
0
2 886
6
Перейти к ответу Данный вопрос помечен как решенный

Ответы 6

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

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

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

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

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

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

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

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

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

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

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

Честно говоря, я не вижу в этом значимости удаленного взаимодействия .NET и CORBA. Можете ли вы предоставить более конкретные указатели?

sanity 18.09.2008 04:33

Кроме того, на самом деле я ищу объяснение того, как системы сбора мусора как перемещают объекты.

sanity 18.09.2008 04:38

@Sanity - Роб Уокер рекомендует эти технологии как средство для лучшего понимания их стратегий относительно того, почему и как они делают то, что делают.

mP. 07.05.2009 15:24

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

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

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

Интересно, я исследую это. Но разве поиск ссылок на объект во всей куче не является крайне неэффективным?

sanity 18.09.2008 04:47

И да и нет. В некотором смысле это то, что в любом случае должна делать фаза «отметки», чтобы выяснить, есть ли ссылка на объект, который он планирует уничтожить. Поэтому сотни человеко-лет работы были потрачены на оптимизацию инкрементных сборщиков мусора, чтобы не делать все сразу.

Steve Jessop 18.09.2008 04:54
Ответ принят как подходящий

Ссылаясь на комментарий выше про хождение по куче.

Разные сборщики мусора делают это по-разному.

Обычно копирующие сборщики при обходе кучи не обходят все объекты в куче. Скорее они перемещают ЖИВЫЕ объекты в куче. Подразумевается, что если он доступен из «корневого» объекта, объект жив.

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

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

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

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

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

Похоже, вы ищете распределенный кеш, что-то вроде terracotta или oracle java objece cache (ранее tangersol).

Я думаю, что продукт, о котором вы говорите, называется "Coherence", а компанией была Tangosol.

Tnilsson 18.09.2008 12:40

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

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

Разница в том, что, насколько вам известно, Terracotta не предоставляет «удаленных» ссылок на объекты - на самом деле все «удаленное» понятие RMI, JMS и т. д. Полностью отсутствует при использовании Terracotta.

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

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

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

Кроме того, в отличие от любого предшествующего решения, ссылки на объекты поддерживаются между узлами - это означает, что вы можете использовать ==. Все это часть поддержки модели памяти Java в кластере, что является фундаментальным требованием для того, чтобы «обычная» Java (например, POJO, синхронизация, ожидание / уведомление) работала (ничего из этого не работает, если вы не / не можете сохранить идентичность объекта в кластере).

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

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

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

Вот ссылка.

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

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

Другие вопросы по теме