Как JVM гарантирует, что System.identityHashCode () никогда не изменится? - PullRequest
67 голосов
/ 30 июня 2009

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

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

Ответы [ 5 ]

39 голосов
/ 30 июня 2009

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

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

16 голосов
/ 30 июня 2009

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

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

2 голосов
/ 12 июня 2015

Заголовок объекта в HotSpot состоит из указателя класса и слова «отметка».

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

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

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

0 голосов
/ 30 июня 2009

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

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

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

...