Как JVM узнает, сколько считывать в начальном адресе при чтении данных объекта?

Я изучил следующее. Заголовок объекта состоит из слова метки и указателя класса. В случае массива он дополнительно имеет заголовок размера.

Другими словами, в заголовке данных объекта нет информации о размере. Итак, как JVM узнает, как далеко читать от начального адреса при чтении данных объекта?

Как вы думаете, почему размер объекта необходим для чтения данных объекта? Чтобы прочитать данные объекта, вам просто нужно знать, где эти данные...

Sweeper 02.02.2023 08:50

Я думаю, что нужно сделать связанную проверку

korjun1993 02.02.2023 10:19
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
3
2
89
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Отличие массива от «нормального» объекта в том, что массивы могут иметь разные размеры, в то время как все объекты данного класса имеют одинаковый размер. В некотором смысле размер объектов, не являющихся массивами, сохраняется, но не для каждого объекта, а только один раз в данных соответствующего класса (отсюда и указатель класса).

Что касается доступа к данным в массиве/объекте, есть еще одно отличие: при доступе к элементу массива JVM должна выполнять проверку границ, для чего требуется знать размер массива. Однако при доступе к полю обычного объекта это не так, поскольку количество/позиции всех полей фиксированы (и известны во время загрузки класса) для каждого объекта данного класса. Поэтому обычно для доступа к его данным знание размера объекта на самом деле не требуется. Однако я хочу релятивизировать комментарий Sweeper: JVM необходимо знать размер объектов, не являющихся массивами, например, при их перемещении в рамках уплотнения сборки мусора.

Правильно ли я понимаю? Для массивов доступ к данным осуществляется по индексу. Необходима проверка привязки, поскольку значение индекса может быть недействительным. Однако в случае объектов доступ к данным осуществляется по имени поля. Таким образом, ему не нужно выполнять проверку границ, и ему не нужно знать размер. Затем нужно ли получить доступ к адресу памяти объекта путем вычисления начального адреса + размера байта каждого поля?

korjun1993 02.02.2023 10:18

@ korjun1993 Звучит правильно, да. Начальный адрес + размер заголовка + размер предшествующих полей.

rolve 02.02.2023 10:20

Для завершения: также проверяется действительность доступа к полю. Но доступ к полю всегда будет ссылаться на одно и то же поле (в отличие от потенциально изменяющегося индекса массива), а поля, объявленные классом, также никогда не меняются (в одной среде выполнения), поэтому эта проверка выполняется только один раз верификатором перед кодом. выполняется с первого раза. Как только будет доказано, что он действителен, он всегда будет действительным (кроме потенциального доступа к null), и его не нужно проверять снова.

Holger 03.02.2023 13:48

@Holger, да, прояснил это в ответе.

rolve 03.02.2023 14:40

JVM может определить размер объекта на основе класса объекта и расположения полей объекта в памяти. Когда объект создается, JVM выделяет память для заголовка объекта (слово метки и указатель класса) и его полей. JVM использует класс объекта для определения размера заголовка, а также размера и типов полей.

Рассмотрим массив объектов «Страница», где каждый объект «Страница» имеет два поля: «текст» и «изображения». JVM будет выделять память для заголовка массива (слово метки, указатель класса и заголовок размера) и объекты «Страница». Слово метки, указатель класса и заголовок размера составляют заголовок массива, а объекты «Страница» сохраняются сразу после заголовка.

Когда JVM необходимо прочитать данные для определенного объекта «Страница» в массиве, она начинает с начального адреса массива и сначала считывает слово метки, указатель класса и заголовок размера из заголовка массива. Заголовок размера содержит информацию о размере массива, которую JVM использует для определения количества объектов «Страница» в массиве.

Затем JVM использует указатель класса для определения расположения объектов «Страница» в памяти. JVM знает, что первое поле каждого объекта "Страница" является полем "текст", которое представляет собой строку, поэтому она считывает необходимое количество байтов, чтобы получить значение поля "текст" для конкретного объекта "Страница". она интересуется. Затем JVM знает, что следующим полем является поле «images», которое также является строкой, поэтому она считывает необходимое количество байтов, чтобы получить значение поля «images» для той же «Page». " объект.

Используя указатель klass для определения расположения полей в памяти, JVM может эффективно и точно считывать данные для конкретных объектов «Страница» в массиве, даже если массив содержит большое количество объектов «Страница». Этот процесс выполняется каждый раз, когда JVM требуется доступ к данным для объекта в массиве, что делает его важной частью системы управления памятью JVM.

На что указывает указатель класса? Это метаданные класса, которые были сгенерированы в области методов загрузчиком классов?

korjun1993 02.02.2023 12:27

Другие вопросы по теме