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