Как JVM гарантирует, что System.identityHashCode() никогда не изменится?

Обычно стандартная реализация Object.hashCode() - это некоторая функция выделенного адреса объекта в памяти (хотя это не обязано JLS). Учитывая, что VM шунтирует объекты в памяти, почему значение, возвращаемое System.identityHashCode(), никогда не изменяется во время жизни объекта?

Если это "одноразовый" расчет (объект hashCode вычисляется один раз и спрятан в заголовке объекта или что-то в этом роде), значит, это означает, что два объекта могут иметь одинаковый identityHashCode ( если они сначала распределяются по одному и тому же адресу в памяти)?

Ответы

Ответ 1

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

Несколько объектов могут иметь один и тот же хэш-код. Такова природа хеш-кодов.

Ответ 2

В ответ на второй вопрос, независимо от реализации, несколько объектов могут иметь один и тот же идентификаторHashCode.

См. ошибка 6321873 для краткого обсуждения формулировки в javadoc и программы для демонстрации неединственности.

Ответ 3

Заголовок объекта в HotSpot состоит из указателя класса и слова "mark".

Исходный код структуры данных для слова метки можно найти файл markOop.hpp. В этом файле есть комментарий, описывающий макет памяти слова метки:

hash:25 --------→| age:4 biased_lock:1 lock:2 (normal object)

Здесь мы видим, что хэш-код идентичности для обычных объектов Java в 32-битной системе сохраняется в слове метки и имеет длину 25 бит.

Ответ 4

Общее руководство для реализации хэш-функции:

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

Ответ 5

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