Насколько велика ссылка на объект в Java и какую именно информацию она содержит?
Как программист, я думаю, что они выглядят как "объект java.lang.Object по адресу 1a234552" или что-то подобное s
в
Object s = "hello";
Это правильно? Поэтому все ли ссылки имеют фиксированный размер?
4 ответа
Хотя на многих виртуальных машинах размер ссылки равен собственному размеру указателя (т. Е. 32 бита для 32-битной JVM и 64-битной для 64-битной JVM), это не гарантируется - и, в частности, HotSpot или делает это сейчас или скоро будет поддерживать " Сжатые упы ", которые являются 32-битными ссылками в 64-битной JVM. (Это не означает, что каждая ссылка сжата - прочитайте связанную статью для получения дополнительной информации, и об этом также есть много постов в блоге.)
В ответ на другой комментарий обратите внимание, что сама ссылка, как правило, является просто способом обращения к самому объекту. Является ли это прямым указателем памяти или нет, его цель - получить данные для объекта. Это в основном все, что действительно имеет значение. Если есть некоторые "запасные" биты (например, это 64-битная ссылка, и вам не нужна вся эта ширина только для представления местоположения объекта), то виртуальная машина может использовать эти данные для другой информации, такой как ее тип, которая может позволить некоторые оптимизации. (См. Комментарий Тома для более подробной информации.)
Сам объект содержит информацию о типе (вероятно, в форме ссылки на экземпляр Class
или что-то подобное - я не знаю достаточно подробно), а также другие необходимые "вещи" в заголовке, прежде чем вы получите пользовательские данные для объекта.
Он не является частью спецификации JLS или JVM, но на практике это будет адрес: 32-битный на 32-битном ЦП, 64 на 64.
pqism: Хорошо, понял, потому что после компиляции мы больше не заботимся об объявленном типе?
Мы заботимся. Вот почему объекты класса есть. Фактически, из других ответов вы можете видеть, что мы заботимся о типах во время выполнения, чтобы оптимизировать методы работы с ними, помещая часть информации о типах в ссылку.
Я просто хочу добавить свои 0,02 доллара на 64-bit
платформы, ссылка может иметь 32 bit
s или 64 bit
с.
Это может быть 32 bit
размер, когда Compressed OOP
включен (по умолчанию включен).
По-другому это может быть 32 bit
s - это когда куча меньше, чем 4 GB
и вписывается в начальное виртуальное пространство 4 GB
. Например:
0 4GB
..................................................
| < your heap fits here> |
В таком случае исходный код говорит, что это UnscaledNarrowOop
тип выравнивания кучи, и для этого типа ссылки имеют 32 бита.
Размер ссылки на объект зависит от JVM и архитектуры машины. Обычно на 32-битной машине это 32 бита, а на 64-битной - 64 бита. Тем не менее, я думаю, что OpenJDK 7 JVM будет поддерживать "сжатые указатели", которые сэкономят место на 64-битных машинах.
Информация о типе объекта хранится в самом объекте; то есть, если вы следуете 32-битному или 64-битному указателю (или, скорее, дескриптору) на объект, вы найдете другой указатель на Class
экземпляр, который описывает тип, а также поля данных объекта.
Большинство людей склонны видеть ссылку на объект как указатель на язык C-like-memory. Хотя это технически неверно, большинство реализаций реализуют его как указатель. Например, в случае указателей на сжатые объекты JVM хранит только биты с 3 по 34 64-битного указателя на 64-битной платформе. Другие реализации также могут использовать другую схему: ссылка может быть указателем на массив указателей, содержащий все объекты.