Я часто слышал, что эти методы (Object.hashCode
и System.identityHashCode
) возвращают адрес объекта или что-то быстро вычисленное из адреса; но я также уверен, что сборщик мусора перемещает и сжимает объекты. Поскольку хэш-код не может быть изменен, это представляет проблему. Я знаю, что это не то, что нужно знать для повседневной работы, но мне хотелось бы разобраться во внутреннем устройстве. Итак, кто-нибудь знает, как это реализовано в Java? Или .NET, поскольку они, вероятно, похожи.
Если сборщик мусора Java перемещает объекты, что такое Object.hashCode и System.identityHashCode?
Ответы (3)
Реализация .NET намеренно не публикуется (и когда вы попытаетесь ее декомпилировать, вы обнаружите, что она выполняет неуправляемый вызов фреймворка). Единственная документация как таковая находится здесь, заявляет, что «не гарантируется создание разных значений для каждого объекта» и «может меняться в зависимости от версии платформы». Делать какие-либо предположения о том, как это на самом деле работает, вероятно, не рекомендуется.
Java более понятна (хотя, вероятно, может отличаться в зависимости от JVM), и конкретно рассматривается в этом вопросе: Будет ли .hashcode () возвращать другое int из-за сжатия пространства владения?
Суть реализации Java заключается в том, что по контракту значение хэш-кода объекта не имеет значения, пока оно не будет получено в первый раз. После этого он должен оставаться постоянным. Таким образом, GC, перемещающий объект, не имеет значения, пока не будет вызван метод hashcode () объекта в первый раз. После этого используется кешированное значение.
IdentityHashCode не изменяется для объекта. Таким образом, любое перемещение происходит ниже этого уровня.
Элементарная реализация будет иметь отображение логический адрес -> физический адрес для каждого объекта.
Более сложные реализации будут иметь отображение только на уровне страницы, поэтому, возможно, последние 6 бит - это смещение памяти, а остальные - идентификатор страницы. Косвенное обращение произойдет на уровне идентификатора страницы -> фактического адреса страницы.
В .net метод getHash () будет зависеть от GC, и поэтому рекомендуется, чтобы разработчики использовали свои собственные реализации хеширования. В настоящий момент я не могу найти ссылку на внутреннюю реализацию. Позже выложу, если найду ..
Нашел ссылку ... На этот вопрос ответили здесь
hashCode()
, является адресом физической памяти. В общем, сборщик мусора может перемещать объекты между молодыми и арендованными пространствами без ведома приложения ... - person Lukas Eder   schedule 26.08.2011