#java #jvm-hotspot
#java #jvm-точка доступа
Вопрос:
public class MemoryTest {
final String fs = "final String"; //A
final int fi = 1; //A
String s = "Member String"; //A
int i = 2; //A
final static String fss = "final static String"; //B
final static int fsi = 3; //B
static String ss = "static String"; //C
static int si = 4; //C
public static void main(String args[]){
MemoryTest m = new MemoryTest();
}
}
[мой ответ]
//A: Когда объект создается из класса, он копируется в объект по ссылке на постоянный пул области методов, и созданному объекту присваивается это значение.
=> расположение: куча
//B : Существует в постоянном пуле области методов, не скопирован в object
=> местоположение: постоянный пул области методов
// C : Когда механизм выполнения запускает переменную класса «static {}» в области методов, она будет назначена ссылкой на постоянный пул в области методов.
=> местоположение : переменная класса области методов
Комментарии:
1. Ваш заголовок посвящен полям-членам, но ваш вопрос касается объектов. Что это?
2. кому: user207421 — Это вопрос о взаимосвязи между полями-членами и объектом.
Ответ №1:
//A: Когда объект создается из класса, он копируется в объект по ссылке на постоянный пул области методов, и созданному объекту присваивается это значение.
Неверно.
-
Пул констант, о котором вы говорите, является частью файла classfile, и на значения в пуле нельзя ссылаться при запуске программ1. Интерпретатор и JIT-компилятор используют их под капотом, но это невидимо на уровне приложения.
-
Пул констант является общим для всех методов в файле класса. Это не является частью какой-либо области методов.
В случае строковых литералов и константного выражения со строковым значением значение в пуле констант classfile используется для создания String
объекта2. Затем эти объекты interned
помещаются в пул строк среды выполнения и добавляются к дескриптору среды выполнения.
Обратите внимание, что пул строк отличается от пула констант. В современных JVM пул строк представляет собой структуру данных в обычной куче.
=> расположение: куча
Правильно. String
Объект и MemoryTest
объект, который содержит fs
переменные fi
, s
i
и, , оба находятся в куче; т. е. все эти переменные находятся в куче.
Переменные s
и fs
содержат ссылки. Переменные i
и fi
содержат простые 32-разрядные целочисленные значения. Они ни на что не ссылаются. Они есть … автономный.
//B : Существует в постоянном пуле области методов, не скопирован в object
Неверно; см. Выше.
Ситуация немного сложная, поскольку ffi
использование значения этой переменной может быть встроено в код компилятором байт-кода. Однако поле все еще существует во время выполнения, и к нему можно получить доступ с помощью отражения или агента отладки.
=> местоположение: постоянный пул области методов
Неверно. String
Объект находится в пуле строк, как указано выше. Переменные fss
и fsi
находятся в классе static frame, который также находится в куче.
// C : Когда механизм выполнения запускает переменную класса «static {}» в области методов, она будет назначена ссылкой на постоянный пул в области методов.
Неверно; см. Выше. (Хотя si
они не будут встроены.)
=> местоположение : переменная класса области методов
Неверно; см. Выше.
1 — Хорошо, вы могли бы написать код приложения для самостоятельного анализа файла класса. Или вы могли бы (теоретически) использовать машинный код, чтобы найти, где JVM кэшировала пул констант, и извлечь информацию. Просто не делайте этого.
2 — Раньше это делалось быстро, но последние JVM создают String
объекты лениво при первом использовании строкового литерала. На самом деле возможно написать тест, чтобы определить, когда объект создан. Джон Скит однажды показал мне 🙂