Если сборщик мусора Java перемещает объекты, что такое Object.hashCode и System.identityHashCode?

Я часто слышал, что эти методы (Object.hashCode и System.identityHashCode) возвращают адрес объекта или что-то быстро вычисленное из адреса; но я также уверен, что сборщик мусора перемещает и сжимает объекты. Поскольку хэш-код не может быть изменен, это представляет проблему. Я знаю, что это не то, что нужно знать для повседневной работы, но мне хотелось бы разобраться во внутреннем устройстве. Итак, кто-нибудь знает, как это реализовано в Java? Или .NET, поскольку они, вероятно, похожи.


person Rob N    schedule 26.08.2011    source источник
comment
У вас есть источник статьи, где говорится, что сборщик мусора может перемещать объекты?   -  person Amir Raminfar    schedule 26.08.2011
comment
@Amir Я почти уверен, что большинство реализаций JVM реализуют сжатие мусора, которое может перемещать объект в памяти.   -  person dlev    schedule 26.08.2011
comment
@Amir: Определенно существуют сборщики мусора, которые это делают (см. ru. wikipedia.org/wiki/), и ни один язык не предписывает подобные детали реализации GC. Или, более прагматично: Google подтвердит, что по крайней мере некоторые JVM используют GC поколений, GC поколений по определению движется. См. Также java.sun.com/docs/hotspot/gc1.4.2/ faq.html, в котором прямо говорится, что молодое поколение управляется копирующим (т. е. также перемещающим) сборщиком мусора.   -  person    schedule 26.08.2011
comment
Я не думаю, что адрес, используемый hashCode(), является адресом физической памяти. В общем, сборщик мусора может перемещать объекты между молодыми и арендованными пространствами без ведома приложения ...   -  person Lukas Eder    schedule 26.08.2011
comment
@Amir Вот одна статья: ibm.com/developerworks/ibm/library/ i-gctroub, который я нашел после поиска в Google компактного сборщика мусора java.   -  person Rob N    schedule 26.08.2011


Ответы (3)


Реализация .NET намеренно не публикуется (и когда вы попытаетесь ее декомпилировать, вы обнаружите, что она выполняет неуправляемый вызов фреймворка). Единственная документация как таковая находится здесь, заявляет, что «не гарантируется создание разных значений для каждого объекта» и «может меняться в зависимости от версии платформы». Делать какие-либо предположения о том, как это на самом деле работает, вероятно, не рекомендуется.

Java более понятна (хотя, вероятно, может отличаться в зависимости от JVM), и конкретно рассматривается в этом вопросе: Будет ли .hashcode () возвращать другое int из-за сжатия пространства владения?

Суть реализации Java заключается в том, что по контракту значение хэш-кода объекта не имеет значения, пока оно не будет получено в первый раз. После этого он должен оставаться постоянным. Таким образом, GC, перемещающий объект, не имеет значения, пока не будет вызван метод hashcode () объекта в первый раз. После этого используется кешированное значение.

person Chris Shain    schedule 26.08.2011
comment
Так что мне любопытно узнать. Что JVM делает со всеми ссылками при перемещении объекта? Все ли они просто символические отсылки? или нужно обновлять каждую ссылку на новое место? - person Amir Raminfar; 26.08.2011
comment
@AmirRaminfar - Короткий ответ заключается в том, что он обновляет все ссылки, но есть некоторые хитрые вещи, которые гарантируют, что это можно сделать эффективно. Длинный ответ - купить / прочитать хороший учебник по сборке мусора. - person Stephen C; 04.07.2013

IdentityHashCode не изменяется для объекта. Таким образом, любое перемещение происходит ниже этого уровня.

Элементарная реализация будет иметь отображение логический адрес -> физический адрес для каждого объекта.

Более сложные реализации будут иметь отображение только на уровне страницы, поэтому, возможно, последние 6 бит - это смещение памяти, а остальные - идентификатор страницы. Косвенное обращение произойдет на уровне идентификатора страницы -> фактического адреса страницы.

person Dilum Ranatunga    schedule 26.08.2011
comment
... или на что ссылается @Chris Shain в своем ответе ;-) - person Dilum Ranatunga; 26.08.2011

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

Нашел ссылку ... На этот вопрос ответили здесь

person Osama Javed    schedule 26.08.2011