2. Какие области входят в область данных времени выполнения?
3. Какие данные хранятся в стеке и куче соответственно?
4. Почему нам следует заменить постоянное поколение (PermGen) метапространством (MetaSpace)?
5. Понимаете ли вы основную структуру кучи? При каких обстоятельствах объект перейдет в старое поколение?
6. В какой области памяти размещаются крупные предметы?
7. Каков процесс создания объектов Java?
Вопрос ответ
1. Из каких частей состоит JVM?
Ответ: JVM — это исполняемый файл.байт-код (.class) файловый виртуальный компьютер, который также обеспечивает управление памятью, сборку мусора и другие механизмы. Он содержит следующие основные части.
Подсистема загрузки классов: отвечает за загрузку файлов байт-кода (.class) в JVM.
Область данных времени выполнения: это область памяти, используемая JVM во время выполнения.
Механизм выполнения: отвечает за интерпретацию или компиляцию байт-кода в машинный код для выполнения процессором.
Интерфейс собственной библиотеки: предоставляет набор API для вызова собственных библиотек, написанных в операционной системе или на других языках.
2. Какие области входят в область данных времени выполнения?
Ответ: Область данных времени выполнения — это область памяти, выделяемая JVM при выполнении программы Java.
Счетчик программ: это небольшая область памяти и адрес инструкции байт-кода, выполняемой потоком в данный момент. Если поток выполняет собственный метод, значение этого счетчика не определено.
Стек виртуальной машины Java: каждый поток при создании создает стек виртуальной машины, который используется для хранения таблицы локальных переменных потока, кадра операнда, динамической ссылки, информации о выходе метода и т. д. Стек виртуальной машины Java содержит несколько кадров стека. Процесс от каждого вызываемого метода до завершения выполнения соответствует процессу помещения кадра стека в стек виртуальной машины.
Стек собственных методов: это пространство, подготовленное JVM для запуска собственных методов. Он имеет функции, аналогичные стеку виртуальной машины Java. Это модель памяти, которая описывает процесс выполнения собственных методов.
Куча: используется для хранения почти всех экземпляров объектов и массивов и является основной областью, в которой работает сборщик мусора.
Область метода: используется для хранения информации о классе, констант, статических переменных, кода, скомпилированного JIT-компилятором, и т. д., загружаемых JVM. До JDK1.8 он был реализован как постоянное поколение. Начиная с JDK1.8, постоянное поколение заменяется исходным пространством. Metaspace использует локальную память, а не динамическую память.
3. Какие данные хранятся в стеке и куче соответственно?
Ответ: Данные хранятся в стеке (стеке виртуальной машины Java):
Таблица локальных переменных: в основном используется для хранения параметров метода и локальных переменных внутри метода. Типы данных включают базовые типы данных и ссылки на объекты.
Стек операндов: используется для временного хранения инструкций операции и промежуточных результатов во время выполнения метода.
Динамическая ссылка: ссылка на пул констант класса, к которому принадлежит метод, используемая для разрешения ссылок на символы в методе.
Адрес возврата метода: хранит адрес следующей инструкции, выполняемой после вызова метода. Данные, хранящиеся в куче:
Экземпляр объекта: Экземпляр объекта, созданный с помощью нового ключевого слова в программе, включая свойства и методы объекта.
Массив: все типы массивов, включая массивы базовых типов и массивы объектов.
4. Почему нам следует заменить постоянное поколение (PermGen) метапространством (MetaSpace)?
Ответ: Замена постоянной генерации на метапространство предназначена главным образом для решения некоторых проблем и ограничений, присущих постоянной генерации, а также для улучшения производительности и гибкости JVM.
Повысьте гибкость и эффективность управления памятью. Размер памяти постоянной генерации устанавливается при запуске JVM и не может регулироваться динамически. Metaspace использует локальную память вместо кучи Java, и ее размер можно динамически регулировать по мере необходимости.
Решите проблему выгрузки классов и сборки мусора: поведение GC постоянной генерации сложное и непредсказуемое, а эффективность переработки низкая.
Обеспечьте лучшую производительность и стабильность. Использование метапространства делает управление памятью JVM более унифицированным и последовательным, поскольку метапространство, как и другие области памяти, управляется с использованием локальной памяти. Это упрощает стратегии управления памятью и повышает общую производительность и стабильность.
Упрощение управления памятью JVM
5. Понимаете ли вы основную структуру кучи? При каких обстоятельствах объект перейдет в старое поколение?
Ответ: Базовая структура кучи в основном состоит из нового поколения, старого поколения и постоянного поколения. После JDK8 постоянное поколение заменяется метапространством и использует для хранения локальную память.
Кайнозойское поколение: развитие нового поколения подразделяется на область Эдема и две области выживания (Выживший 0 и Выживший 1).
Область Эдема: вновь созданные объекты сначала выделяют память в области Эдема.
Область выживания (S0, S1): используется для хранения объектов, переживших сборку мусора нового поколения. После каждого второстепенного GC уцелевшие объекты будут копироваться туда и обратно между этими двумя областями.
Старое поколение: объекты, которые все еще живы после нескольких второстепенных сборок мусора. Сбор мусора (Major GC или Full GC) в старом поколении выполняется реже.
Постоянное поколение/метапространство: используется для хранения метаданных классов, включая определения классов, константы, статические переменные, скомпилированный код «точно в срок» и т. д.
Ситуация, когда объект находится в старом поколении:
Достигнут порог возраста: у каждого объекта есть возраст, когда память выделяется в новом поколении, и этот возраст будет увеличиваться на 1 после каждого второстепенного GC. Когда возраст достигнет определенного порога (по умолчанию — 15), объект будет переведен в старое поколение.
Большой объект: если объект слишком велик и превышает порог, установленный JVM, объект будет напрямую выделять пространство в старом поколении.
Недостаточно места в зоне выживших: если в зоне выживших недостаточно места для размещения всех выживших объектов во время Minor GC, эти объекты будут
Динамическое определение возраста объекта: Если размер всех объектов одного возраста в пространстве Выжившего превышает половину пространства Выжившего, то объекты, возраст которых больше или равен этому возрасту, могут напрямую перейти в старое поколение.
// 动态年龄计算代码
uint ageTable::compute_tenuring_threshold(size_t survivor_capacity){//survivor_capacity是survivor空间的大小size_t desired_survivor_size =(size_t)((((double) survivor_capacity)*TargetSurvivorRatio)/100);//TargetSurvivorRatio 为50size_t total =0;
uint age =1;while(age < table_size){
total += sizes[age];//sizes数组是每个年龄段对象大小if(total > desired_survivor_size)break;
age++;}
uint result = age < MaxTenuringThreshold ? age : MaxTenuringThreshold;...}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
6. В какой области памяти размещаются крупные предметы?
Ответ: Большие объекты (очень большие массивы и строки) обычно размещаются непосредственно в области памяти старого поколения.Это делается для того, чтобы новое поколение не выполняло частыеВывоз мусораВ это время большие объекты часто копируются между областью Эдема и областью Выжившего, тем самым повышая эффективность сбора мусора. Настройте порог для крупных объектов, чтобы они напрямую входили в старое поколение:
Если класс не был загружен, подключен и инициализирован, JVM сначала загрузит класс. Это включает в себя следующие шаги:
Загрузка: прочитайте файл класса через загрузчик классов и загрузите байт-код класса в память.
Подключение: включает в себя три этапа: проверка, подготовка и разбор. Проверьте правильность файлов классов, подготовьте статические переменные класса и выделите память, а также преобразуйте ссылки на символы в прямые ссылки.
Инициализация: выполнить блок статической инициализации класса и инициализацию статических переменных.
выделение памяти
JVM выделяет память для новых объектов в куче. Размер выделяемой памяти определяется структурой объекта, включая заголовок объекта и данные экземпляра.
JVM имеет два основных способа распределения памяти:
Удар по указателю: если память в куче является регулярной, указатель выделения должен переместиться только на указанное расстояние в область свободной памяти.
Список свободных ресурсов. Если память в куче нерегулярна, JVM необходимо поддерживать список свободных мест и находить соответствующий блок из списка свободных при выделении памяти.
инициализировать нулевым значением
JVM инициализирует все переменные экземпляра объекта значениями по умолчанию. Например, переменные числового типа будут инициализированы значением 0, переменные логического типа — значением false, а переменные ссылочного типа — значением null.
Установить заголовок объекта
Установите информацию заголовка объекта в пространстве памяти объекта, которая включает в себя хеш-код объекта, возраст создания GC, флаг состояния блокировки, блокировку, удерживаемую потоком, смещенный идентификатор потока и т. д.
Инициализация конструктора
Вызовите конструктор объекта, чтобы завершить инициализацию объекта. Сюда входит выполнение явных операций инициализации переменных экземпляра, а также кода в теле конструктора. Конкретные шаги заключаются в следующем:
Выполните блок инициализации экземпляра класса.
Выполните метод конструктора родительского класса сверху вниз в соответствии с иерархией наследования.
Инициализируйте переменные экземпляра явно указанными значениями.
Выполните основную часть метода конструктора класса.