@TOC
不懂JVM看完这一篇文章你就会非常懂了,文章很长,非常详细!!!
Сначала подумайте над некоторыми вопросами
1 Как Java-код, написанный нашими разработчиками, распознается компьютером
Сначала поймите, что компьютер представляет собой двоичную систему, он знает только 01010101
Например, нам часто приходится писать HelloWord.java Как компьютер знает и работает?
HelloWord.java написан нашими программистами, мы люди можем знать, но компьютер не знает
Процесс компиляции файлов JavaИтак, вам нужно скомпилировать:
- Файлы .java, написанные программистом
- Скомпилировано javac в файл байт-кода .class: (Почему он скомпилирован в файл класса, потому что JVM распознает только файлы .class)
- Компилируется JVM в файл, распознаваемый компьютером (для компьютерной системы файл представляет все)
(Это примерное представление о концепции абстрактной живописи)
2 Почему Java считается кроссплатформенным языком
Эта платформа Kua представляет собой платформу Kua, реализованную на промежуточном языке (JVM). В Java есть JVM, которая защищает базовое оборудование и детали уровня инструкций от уровня программного обеспечения, что делает его совместимым с различными системами.
Разве C и C++ не могут похвастаться платформами?
C и C++ должны быть совместимы с разными уровнями разных операционных систем на уровне компилятора.Те, кто писал C и C++, знают, что некоторые коды разных операционных систем различаются.
3 JDK и JRE и JVM
Java см. официальное изображение, Jdk включает Jre, включая JVM в Jre
JVM находится на предпоследнем уровне и может запускаться им на различных платформах (последний уровень).
Большая часть Jre написана на языке C и C++, он является базовой библиотекой классов, которая нам нужна при компиляции java.
Jdk также включает в себя некоторые вещи помимо Jre, эти вещи помогают нам компилировать код Java и некоторые инструменты для мониторинга JVM.
4 Зачем изучать JVM
Зачем изучать JVM, что вы можете сделать с изучением JVM
Прежде всего, подумайте: почему Java может занять развитие на уровне предприятия в течение многих лет из-за управления памятью
我们在java开发中何时考虑过内存管理
不像c和c++还要考虑什么时候释放资源
我们java只需要考虑业务实现就行了
Тогда некоторые люди могут снова захотеть сказать, что JVM проделала все эти операции, почему нам все еще нужно учиться, учиться дерьму
假如:内存出现问题了,出现了内存溢出 ,内存泄漏问题怎么办
Это как человек: обычно мне не нужно думать, какую часть тела я ем, но однажды, если я съем что-то, что есть не следует, я пойду в больницу.
Глубокое изучение JVM
Примечания: JVM — это виртуальная машина Java, виртуальная машина Java — это JVM
1 область данных времени выполнения JVM
Что такое область данных времени выполнения (то есть, где находится наш материал времени выполнения Java)
2 Проанализируйте область данных времени выполнения JVM
2.1 Область метода
- Область методов — это область памяти, совместно используемая всеми потоками, которая используется для хранения таких данных, как информация о классе, константы, статические переменные и код, скомпилированный компилятором JIT, который был загружен виртуальной машиной Java.
- У него есть отдельная команда под названием Non-Heap (не куча). Когда область метода не может удовлетворить требования к выделению памяти, создается исключение OutOfMemoryError.
2.2 Куча Java
- Куча Java — это самый большой участок памяти, которым управляет виртуальная машина Java.Это область памяти, совместно используемая всеми потоками, которая создается при запуске виртуальной машины. Единственной целью этой области памяти является хранение экземпляров объекта.
- Описание в Спецификации виртуальной машины Java состоит в том, что все экземпляры объектов и массивы должны размещаться в куче.
- Куча java — это основная область, управляемая сборщиком мусора, поэтому ее также называют «кучей GC».
- С точки зрения восстановления памяти кучу Java можно разделить на: новое поколение и старое поколение.
- С точки зрения распределения памяти, куча Java, разделяемая потоками, может быть разделена на несколько буферов выделения для отдельных потоков.
- Как бы он ни был разделен, это не имеет никакого отношения к содержимому хранилища, в какой бы области ни хранился экземпляр объекта, дальнейшее деление — это чтобы лучше высвобождать память или выделять память быстрее.
- Согласно Спецификации виртуальной машины Java, куча Java может находиться в физически прерывистом пространстве памяти. Текущие основные виртуальные машины являются расширяемыми (контролируются -Xmx и -Xms). Если в куче нет памяти для завершения выделения экземпляра и куча больше не может быть расширена, будет выдано исключение OutOfMemoryError.
2.3 Регистр счетчика программ
- Счетчик программ — это небольшое пространство памяти, которое можно рассматривать как: сохранить адрес (номер строки) инструкции байт-кода, выполняемой текущим потоком
- Поскольку многопоточность виртуальной машины Java реализуется путем переключения потоков по очереди и распределения времени выполнения процессора, процессор может выполнять инструкции только в одном потоке. Поэтому для восстановления правильной позиции выполнения после переключения потоков каждый поток имеет независимый программный счетчик, а счетчики между каждым потоком не влияют друг на друга и хранятся независимо. Назовите это "потоковой" памятью. Область памяти счетчика программ — единственная область в виртуальной машине, в которой не указано условие OutOfMemoryError.
Резюме: его также можно назвать счетчиком потоков.
пример: Наименьшая единица выполнения в java — это поток, поток предназначен для выполнения инструкций, а выполняемые инструкции в конечном итоге управляются нашим компьютером, то есть процессором. Для запуска на ЦП существует очень нестабильный фактор, называемый стратегией планирования, Эта стратегия планирования основана на временных срезах, то есть на эту инструкцию выделяется текущая наносекунда.
если: Thread A смотрит прямую трансляциюВнезапно видеовызов из потока B захватит квант времени потока A, прервет поток A, и поток A зависнет.Затем видеовызов завершается, что именно в это время должен делать поток А? (Поток — это наименьшая исполнительная единица, у него нет функции памяти, он отвечает только за ее выполнение, тогда эта память определяется:программный счетчик для записи)
2.4 Стеки виртуальных машин Java
- Виртуальная машина Java является приватной для потока, и ее жизненный цикл такой же, как и у потока.
- Стек виртуальной машины описывает модель памяти выполнения метода Java: каждый метод создает кадр стека (Stack Frame) для хранения таблицы локальных переменных, стека операндов, динамической ссылки, выхода метода и другой информации при его выполнении.
объяснять: в каждом стеке виртуальной машины есть единица, и эта единицакадр стека, один метод одинкадр стека. Одинкадр стекаВ нем он должен хранить локальные переменные, стек операндов, динамическую ссылку, экспорт и так далее.
Разборная рамка стека:
- Таблица локальных переменных: используется для хранения наших временных 8 основных типов данных, ссылочных адресов объектов и типов returnAddress. (В returnAddress хранится адрес инструкции байт-кода, который должен быть выполнен после возврата.)
- Стек операндов: для работы используется стек операндов, например, в коде есть i = 6*6, он будет работать в начале, читать наш код, вычислять и затем помещать его в таблицу локальных переменных.
- Динамическое связывание: если в моем методе есть метод service.add(), который необходимо связать с другими методами, это динамическая ссылка, в которой хранится ссылка.
- Выход: какой выход, если выход нормальный, он вернется, если ненормальный, он выдаст исключение
считать:. Будет ли один метод вызывать другой метод, создавая много кадров стека?О: Он будет создан. Если в стеке есть динамическая ссылка, которая вызывает другие методы, будет создан новый кадр стека.Стек в порядке.Один кадр стека вызывает другой кадр стека, а другой кадр стека будет помещен ниже вызывающего.
Что означает стек указывает на кучу?Что значит стек указывает на кучу, то есть как использовать переменные-члены в стеке, в стеке не будут храниться переменные-члены, только адрес приложения, данные в куче и т.д.
Создает ли сам рекурсивный вызов много кадров стека?Рекурсия также создаст несколько кадров стека, то есть продолжит выстраиваться в линию.
2.5 Стек собственных методов
- Стек нативных методов прост для понимания, он очень похож на стек, за исключением того, что у метода есть слово стека с ключевым словом native.
- Это стек выполнения виртуальной машины для службы метода виртуальной машины Java (т.е. байт-кода).
- Метод нативного ключевого слова невидим, и вы должны перейти на официальный сайт Oracle, чтобы загрузить его, прежде чем вы сможете его увидеть, и большая часть исходного кода, измененного с помощью нативного ключевого слова, представляет собой код C и C++.
- Точно так же собственный стек методов представляет собой код C и C++.
3 Структура памяти Java
Область данных времени выполнения была упомянута выше, и здесь есть только несколько небольших компонентов.
3.1 Прямая память
- Прямая память не является частью области данных среды выполнения виртуальной машины и не является областью памяти, определенной в спецификации виртуальной машины Java. Но поскольку это память, она все равно должна быть ограничена размером общей памяти (включая ОЗУ и область подкачки или файл подкачки) машины и адресным пространством процессора.
- В JDK1.4 был недавно добавлен класс NIO (новый ввод/вывод) и введен метод ввода/вывода, основанный на канале (Channel) и буфере (Buffer), который может напрямую выделять память вне кучи с помощью нативной функции. Затем обработайте объект DirectByteBuffer, хранящийся в куче Java, как ссылку на эту память. Это может значительно повысить производительность в некоторых сценариях, избегая копирования данных туда и обратно между кучей Java и Native (собственной) кучей.
Разница между прямой памятью и памятью кучи:Потребление пространства приложением с прямой памятью очень высокопроизводительно, потребление пространства приложения кучи памяти относительно низкое. Производительность ввода-вывода при чтении и записи в прямой памяти лучше, чем в куче, и разница очень очевидна в случае нескольких операций чтения и записи.
Пример кода: (ошибка изменяет значение времени)
package com.lijie;
import java.nio.ByteBuffer;
/**
* 直接内存 与 堆内存的比较
*/
public class ByteBufferCompare {
public static void main(String[] args) {
allocateCompare(); //分配比较
operateCompare(); //读写比较
}
/**
* 直接内存 和 堆内存的 分配空间比较
*/
public static void allocateCompare() {
int time = 10000000; //操作次数
long st = System.currentTimeMillis();
for (int i = 0; i < time; i++) {
ByteBuffer buffer = ByteBuffer.allocate(2); //非直接内存分配申请
}
long et = System.currentTimeMillis();
System.out.println("在进行" + time + "次分配操作时,堆内存:分配耗时:" + (et - st) + "ms");
long st_heap = System.currentTimeMillis();
for (int i = 0; i < time; i++) {
ByteBuffer buffer = ByteBuffer.allocateDirect(2); //直接内存分配申请
}
long et_direct = System.currentTimeMillis();
System.out.println("在进行" + time + "次分配操作时,直接内存:分配耗时:" + (et_direct - st_heap) + "ms");
}
/**
* 直接内存 和 堆内存的 读写性能比较
*/
public static void operateCompare() {
//如果报错修改这里,把数字改小一点
int time = 1000000000;
ByteBuffer buffer = ByteBuffer.allocate(2 * time);
long st = System.currentTimeMillis();
for (int i = 0; i < time; i++) {
buffer.putChar('a');
}
buffer.flip();
for (int i = 0; i < time; i++) {
buffer.getChar();
}
long et = System.currentTimeMillis();
System.out.println("在进行" + time + "次读写操作时,堆内存:读写耗时:" + (et - st) + "ms");
ByteBuffer buffer_d = ByteBuffer.allocateDirect(2 * time);
long st_direct = System.currentTimeMillis();
for (int i = 0; i < time; i++) {
buffer_d.putChar('a');
}
buffer_d.flip();
for (int i = 0; i < time; i++) {
buffer_d.getChar();
}
long et_direct = System.currentTimeMillis();
System.out.println("在进行" + time + "次读写操作时,直接内存:读写耗时:" + (et_direct - st_direct) + "ms");
}
}
Результаты теста:
在进行10000000次分配操作时,堆内存:分配耗时:98ms
在进行10000000次分配操作时,直接内存:分配耗时:8895ms
在进行1000000000次读写操作时,堆内存:读写耗时:5666ms
在进行1000000000次读写操作时,直接内存:读写耗时:884ms
Источник кода: "Киви 0303"
Ссылка:blog.CSDN.net/leaf_0303/ ах...
3.2 Механизм выполнения байт-кода JVM
Основным компонентом виртуальной машины является исполнительный механизм, который отвечает за выполнение байт-кода виртуальной машины.Как правило, пользователи сначала компилируют его в машинный код, а затем выполняют.
«Виртуальная машина» — это понятие, относящееся к «физической машине». Байт-код виртуальной машины не может быть запущен непосредственно на физической машине. Он должен быть скомпилирован в машинный код механизмом выполнения байт-кода JVM, прежде чем его можно будет выполнить на компьютере. физическая машина.
3.3 Система сбора мусора
Во время работы программы будет сгенерировано большое количество мусора памяти (некоторые объекты памяти, на которые не указывают ссылки, относятся к мусору памяти, потому что эти объекты больше не доступны, программа больше не может их использовать, и они программа умерла), чтобы обеспечить производительность программы во время выполнения, виртуальная машина Java постоянно выполняет автоматическую сборку мусора (GC) в процессе работы программы.
Система сбора мусора — это ядро Java, и она тоже незаменима, у Java есть собственный механизм очистки мусора, и разработчикам не нужно чистить его вручную.
4 Механизм сборки мусора JVM
Механизм сборки мусора, упомянутый как GC
GC в основном используется для управления кучей Java. Куча в Java — это самое большое пространство памяти, управляемое JVM, и в основном используется для хранения экземпляров объектов различных классов.
4.1 Что такое механизм сборки мусора
Во время работы программы будет сгенерировано большое количество мусора памяти (некоторые объекты памяти, на которые не указывают ссылки, относятся к мусору памяти, потому что эти объекты больше не доступны, программа больше не может их использовать, и они программа умерла), чтобы обеспечить производительность программы во время выполнения, виртуальная машина Java постоянно выполняет автоматическую сборку мусора (GC) в процессе работы программы.
Сборщик мусора должен время от времени очищать недоступные объекты в памяти кучи. Недостижимые объекты не будут немедленно утилизированы напрямую Выполнение сборщика мусора в программе Java является автоматическим и не может принудительно очищать объект, даже если программист может четко определить, что часть памяти бесполезна, да Должна быть утилизирована, программист не может заставить сборщик мусора освободить блок памяти. Единственное, что может сделать программист, — это «посоветовать» сборщику мусора выполнить его, вызвав метод System.gc, но это не зависит от того, выполнит ли он его и когда. Это также главный недостаток сборщика мусора. Конечно, по сравнению с большим удобством, которое он приносит программистам, этот недостаток не скрывается.
Выполнить GC вручную:
System.gc(); // 手动回收垃圾
4.2 завершить действие метода
- Способ доработки () - это метод, который будет призван выполнить GC перед каждой операцией, вы можете использовать его для выполнения необходимой очистки.
- Он определен в классе Object, поэтому все классы наследуются от него. Подклассы переопределяют метод finalize() для очистки системных ресурсов или выполнения другой работы по очистке. Метод finalize() вызывается для объекта до того, как сборщик мусора удалит его.
пример кода
package com.lijie;
public class Test {
public static void main(String[] args) {
Test test = new Test();
test = null;
System.gc(); // 手动回收垃圾
}
@Override
protected void finalize() throws Throwable {
// gc回收垃圾之前调用
System.out.println("gc回收垃圾之前调用的方法");
}
}
4.3 Разница между новым поколением, старым поколением и постоянным поколением (область метода)
-
Куча в Java — это самое большое пространство памяти, управляемое JVM, и в основном используется для хранения экземпляров объектов различных классов.
-
В Java куча делится на две разные области: молодое поколение (Young) и старое поколение (Old).
Не беспокойтесь о том, почему поколение разделилось, потом будут примеры
-
Старость — это только одна область. Новое поколение (Молодое) разделено на три региона: Эдем, От выжившего, К выжившему.
-
Цель этого разделения — позволить JVM лучше управлять объектами в памяти кучи, включая выделение и повторное использование памяти.
-
По умолчанию соотношение нового поколения (Young) к старому поколению (Old) составляет 1:2 (это значение можно задать параметром –XX:NewRatio), то есть: новое поколение (Young) = 1/ 3 размера кучи. Старость ( Old ) = 2/3 размера кучи.
-
Среди них новое поколение (Молодое) подразделяется на Эдем иДве зоны выжившихДве выжившие районы названы из живых и тошервивор, чтобы отличить их.
-
По умолчанию, Edem: From Survivor: To Survivor = 8:1:1 (по параметру -XX: настройка SurvivorRatio), а именно: Eden = 8/10 пространства нового поколения, From Survivor = To Survivor = 1/пространство нового поколения 10.
-
JVM использует только Eden и одну из областей Survivor для одновременного обслуживания объектов, поэтому независимо от того, когда, всегда есть свободная область Survivor.
-
Следовательно, фактическое доступное пространство памяти молодого поколения составляет 9/10 (т.е. 90%) пространства молодого поколения.
-
Постоянная генерация — это область методов JVM. Вот некоторая информация о классе, статические переменные, константы и другие данные, загруженные виртуальной машиной. Вещи в этой зоне труднее перерабатывать, чем старое и молодое поколения.
4.3.1 Почему вы хотите разделить поколения следующим образом:
На самом деле основная причина в том, что предметы могут храниться в разделах по особенностям каждого возраста, что более удобно для утилизации, и принят наиболее подходящий алгоритм сбора:
-
В новом поколении каждая сборка мусора обнаружила, что большое количество объектов было уничтожено.Выживает лишь небольшое количество объектов, используется алгоритм репликации, и только стоимость копирования небольшого количества объектов выживания может быть завершена.
-
В старости, потому что объект имеет высокую скорость выживаемости, и необходимо использовать дополнительное пространство, чтобы выделить его, необходимо использовать алгоритм «Mark-Clean» или «Mark-Clean».
Новое поколение разделено на две области: Эдем и Выживший (откуда и куда, которые здесь называются одной областью). Помимо старости, есть еще три направления. Сначала данные будут выделены в область Eden (конечно, есть особые случаи, если это большой объект, он будет непосредственно помещен в старость (крупные объекты относятся к объектам Java, которые требуют много непрерывного пространства памяти) , Когда в Эдеме недостаточно места, он будет запускать jvm, чтобы инициировать Minor GC. Если объект переживет Minor-GC и может быть принят пространством Survivor, он будет перемещен в пространство Survivor. Установите его возраст до 1, и объект будет выживать каждый раз в Survivor Minor GC, возраст увеличивается на 1. Когда возраст достигает определенного уровня (по умолчанию 15), он будет повышен до старого поколения. возраст поощрения старшего поколения может быть установлен.
4.3.2 Второстепенный GC, Основной GC, Полный GC разница и условия срабатывания
-
Второстепенный GC — это GC нового поколения, который относится к действию сборки мусора, которое происходит в новом поколении. Поскольку большинство java-объектов умирают, Minor GC выполняется очень часто, и скорость восстановления, как правило, выше.
-
Основной сборщик мусора — это сборщик мусора старого поколения, который относится к сборщику мусора старого поколения.Обычно основной сборщик мусора выполняется вместе с второстепенным сборщиком мусора. Major GC намного медленнее, чем Minor GC.
-
Полный ГХ - убирать все куча пространства, в том числе молодого поколения и старый год
Незначительные условия триггера GC обычно являются:
- Когда область Эдема заполнена, запускается MinorGC. То есть при подаче заявки на объект обнаруживается, что площади eden не хватает, и срабатывает MinorGC.
- Размер вновь созданного объекта > оставшееся место в Эдеме
Условия триггера Major GC и Full GC обычно следующие:Основной сборщик мусора обычно эквивалентен полному сбору мусора.
- Средний размер объектов, перемещаемых в старое поколение каждый раз > оставшегося пространства старого поколения
- После Minorgc живых объектов над оставшимися лет
- Недостаточное пространство постоянного поколения
- Выполнить System.gc()
- Исключение CMS GC
- Куча памяти выделяет очень большие объекты
4.4 Как определить, жив ли объект
4.4.1 Подсчет ссылок
-
Подсчет ссылок означает, что если объект не указан на любую ссылку, он может рассматриваться как мусор. Недостатком этого способа является то, что существование колец не может быть обнаружено.
-
Прежде всего, необходимо отметить, что, по крайней мере, основные виртуальные машины Java не используют алгоритмы подсчета ссылок для управления памятью.
-
Что такое метод подсчета ссылок: при создании каждого объекта счетчик привязывается к объекту. Счетчик увеличивается на единицу всякий раз, когда есть ссылка на объект; счетчик уменьшается на единицу всякий раз, когда ссылка на него удаляется. Таким образом, когда нет ссылки на объект, счетчик равен 0, что означает, что объект умирает.
Преимущества подсчета ссылок:
- Реализация алгоритма подсчета ссылок проста, эффективность суждения также очень высока, в большинстве случаев это хороший алгоритм.
Недостатки подсчета ссылок:
- Mainstream Java Virtual Machine внутри приложения не использует алгоритм ссылки для управления памятью, наиболее важной причиной в том, что трудно решить проблему взаимных круговых ссылок между объектами.
- Например:
package com.lijie;
public class Test {
public Object object = null;
public static void main(String[] args) {
Test a = new Test();
Test b = new Test();
/**
* 循环引用,此时引用计数器法失效
*/
a.object = b;
b.object = a;
a = null;
b = null;
}
}
Сценарии применения метода подсчета ссылок:
- Рекомендуется не использовать
4.4.2 Анализ доступности
- Этот метод заключается в поиске вниз от корней GC, а путь, пройденный поиском, представляет собой цепочку ссылок. Когда объект не использует какую-либо цепочку ссылок на GC Roots, это доказывает, что объект недоступен, указывая на то, что его можно переработать.
-
На приведенном выше рисунке объекты Object1, Object2, Object3, Object4 и Object5 доступны для корней GC, что означает, что они являются объектами, на которые ссылаются, и уцелевшие объекты не могут быть повторно использованы.
-
Хотя Object6, Object7 и Object8 связаны друг с другом, они недоступны для GC Roots, поэтому они являются объектами, которые могут быть переработаны.
Те, которые можно использовать как GC Roots:
1、虚拟机栈(栈帧中的本地变量表)中引用的对象;
2、方法区中类静态属于引用的对象;
3、方法区中常量引用的对象;
4、本地方法栈中JNI(即一般说的Native方法)引用的对象。
等
Преимущества алгоритма достижимости:
- Решите задачу взаимной круговой ссылки.
Преимущества алгоритма достижимости:
- В настоящее время нет недостатков по сравнению с подсчетом ссылок
Сценарии применения алгоритма достижимости:
- Это алгоритм основные виртуальные машины используются
4.5 Стратегия механизма сборки мусора (также известная как алгоритм GC)
4.5.1 Подсчет ссылок
При создании каждого объекта счетчик привязывается к объекту. Счетчик увеличивается на единицу всякий раз, когда есть ссылка на объект; счетчик уменьшается на единицу всякий раз, когда ссылка на него удаляется. Таким образом, когда нет ссылки на объект, счетчик равен 0, что означает, что объект мертв, и объект должен быть удален сборщиком мусора.
Преимущества подсчета ссылок:
- Реализация алгоритма подсчета ссылок проста, а эффективность суждения также очень высока.
Недостатки подсчета ссылок:
- Основная виртуальная машина Java внутри приложения не использует алгоритм подсчета ссылок для управления памятью, наиболее важная причина заключается в том, что трудно решить проблему взаимных циклических ссылок между объектами.
- Например:
package com.lijie;
public class Test {
public Object object = null;
public static void main(String[] args) {
Test a = new Test();
Test b = new Test();
/**
* 循环引用,此时引用计数器法失效
*/
a.object = b;
b.object = a;
a = null;
b = null;
}
}
Сценарии применения метода подсчета ссылок:
- Рекомендуется не использовать
4.5.2 Алгоритм маркировки-развертки
Бит флага сохраняется для каждого объекта, записывая состояние объекта (активен или мертв). Он разделен на два этапа: один — этап маркировки, на этом этапе бит маркировки обновляется для каждого объекта, чтобы проверить, является ли объект мертвым; второй этап — этап очистки, который очищает мертвые объекты и выполняет сборщик мусора. операция.
Преимущества алгоритма маркировки-развертки:
- Это может решить проблему круговой ссылки
- Перезагружать при необходимости (когда памяти мало)
Недостатки алгоритма маркировки-развертки:
- При рециркуляции приложение нужно приостановить, то есть остановить мир.
- Неэффективная маркировка и очистка, особенно при большом количестве объектов для сканирования
- Это вызовет фрагментацию памяти (приведет к очевидному пространству памяти, но из-за разрывности невозможно применить для чуть большего объекта),
Сценарии применения алгоритма удаления меток:
- Алгоритм, как правило, используется в старые времена, потому что жизненный цикл объекта старости больше.
4.5.3 Алгоритмы маркировки-сопоставления
Алгоритм пометки-очистки и алгоритм пометки-сжатия очень похожи, но алгоритм пометки-сжатия находится поверх алгоритма пометки-очистки для решения фрагментации памяти (некоторые люди называют «алгоритм очистки пометки» для «алгоритма пометки-сжатия»). ")
Метод пометки и очистки является улучшенной версией метода пометки и очистки. Точно так же на этапе маркировки алгоритм также помечает все объекты как живые и мертвые, отличие состоит в том, что на втором этапе алгоритм не убирает непосредственно мертвые объекты, а помечает все уцелевшие объекты. другое пространство и очистить все оставшиеся объекты. Это достигает цели маркировки-организации.
Преимущества алгоритма организации маркировки:
- Решить проблему фрагментации памяти, вызванную алгоритмом маркировки-развертки,
Недостатки алгоритма маркировки-очистки:
- На этапе уплотнения ссылки необходимо обновлять из-за перемещения доступных объектов.
Сценарии применения алгоритма организации разметки:
- Этот алгоритм обычно используется в пожилом возрасте, потому что жизненный цикл объекта в пожилом возрасте относительно долог.
4.5.4 Алгоритм репликации
Алгоритм делит память на две части поровну, а затем использует только одну часть за раз.Когда эта часть памяти заполнена, он копирует все уцелевшие объекты в памяти в другую память, а затем очищает предыдущую память, и использует только эту часть.Часть памяти, цикл продолжается.
Этот алгоритм и алгоритм завершения тегов не реплицируются в одной и той же области, а копируют все уцелевшие объекты в другую область.
Преимущества алгоритма репликации:
- В случае нескольких выживших объектов он имеет высокую производительность и может решить проблему обновления ссылок, вызванную фрагментацией памяти и очисткой меток, одним из алгоритмов сборки мусора Java.
Недостатки алгоритма репликации::
- Это приведет к некоторой трате памяти. Однако размер блока памяти можно соответствующим образом отрегулировать в соответствии с реальной ситуацией; если количество выживших объектов относительно велико, производительность алгоритма репликации будет очень низкой.
Сценарии применения алгоритма репликации:
- Алгоритм репликации обычно используется в новом поколении, потому что объекты в новом поколении, как правило, умирают, а количество выживших объектов невелико, поэтому эффективность копирования с использованием алгоритма репликации относительно высока.
- jvm Heap (куча) памяти делится на старое и новое поколение. Эдем и новое поколение, в свою очередь, делятся на два Survivor Space (область выживших), затем Eden -> Survivor Space между алгоритмом репликации To Survivor и реализацией.
- Но алгоритм репликации jvm в приложении, а не памяти 1:1 к делению, так что пустая трата памяти. Общий jvm 8:1. То есть Eden Zone: From area: To area соотношение всегда 90% пространства можно использовать для создания объектов, а оставшиеся 10% используются для хранения восстановленных объектов выживания.
4.5.5 Алгоритм генерации (основные алгоритмы — это четыре вышеуказанных, это дополнительные)
Этот алгоритм делит память на несколько блоков в соответствии с жизненным циклом объекта, новым поколением и старым поколением, чтобы можно было принять наиболее подходящий алгоритм сбора в соответствии с характеристиками каждого поколения. Этот алгоритм можно понять, сосредоточившись на идее. Объекты нового поколения умирают, а количество объектов велико.Пока эта область сканируется, эффективность сборки мусора может быть значительно повышена. Кроме того, старые объекты хранятся в течение длительного времени, поэтому нет необходимости часто сканировать старые объекты, чтобы избежать накладных расходов, вызванных сканированием.
Кайнозой
- В новом поколении каждый раз, когда сборщик мусора обнаруживает, что большое количество объектов умирает, а выживают лишь немногие.Используя алгоритм репликации, сборку можно завершить только за счет копирования небольшого количества уцелевших объектов.
старость
- В старости, потому что уровень выживаемости объекта высока, и нет дополнительного пространства, чтобы выделить его, он должен быть переработан методом «Mark-Sweep Method или алгоритм сортировки отметки».
5 Сборщик мусора
5.1 Что такое сборщик мусора?
- Сборщик мусора — это конкретная реализация алгоритма сборки мусора (метод подсчета ссылок, метод четкой маркировки, метод сортировки меток и алгоритм репликации).Сборщики мусора, предоставляемые разными сборщиками мусора и разными версиями JVM, могут сильно различаться.
- Я беру JDK8 в качестве стандарта:
На рисунке показано 7 разных поколений коллекторов:Последовательный, ParNew, Параллельная очистка, CMS, Серийный старый, Параллельный старый, G1
Район, где они расположены, указывает на принадлежность к коллекционерам молодого или старшего поколения:
-
Коллекционеры нового поколения: Serial, ParNew, Parallel Scavenge
-
Сборщики старого поколения: CMS, Serial Old, Parallel Old
-
Сборщик всей кучи: G1
Между двумя коллекторами есть связь, указывающая на то, что их можно использовать вместе:
Serial / Serial Old
Serial / CMS
ParNew / Serial Old
ParNew / CMS
Parallel Scavenge / Serial Old
Parallel Scavenge / Parallel Old
G1
5.2 Подробное объяснение сборщика мусора
уборщик мусора | Рабочая зона | Алгоритм коллекции | рабочий поток | Параллелизм пользовательских потоков | описывать |
---|---|---|---|---|---|
Serial | Пояс первокурсника | алгоритм репликации | один поток | нет | Сборщик нового поколения по умолчанию в клиентском режиме. Просто и эффективно |
ParNew | Пояс первокурсника | алгоритм репликации | Многопоточность | нет | Многопоточная версия Serial, первый выбор в режиме сервера, может использоваться с коллектором CMS нового поколения. |
Parallel Scavenge | Пояс первокурсника | алгоритм репликации | Многопоточность | нет | Цель состоит в том, чтобы достичь управляемой пропускной способности |
Serial Old | ремень старости | Отметить-организовать | один поток | нет | Серийная старая версия, используемая для виртуальных машин в клиентском режиме. |
Parallel Old | ремень старости | Отметить-организовать | Многопоточность | нет | Parallel Scavenge старая версия, приоритет пропускной способности |
CMS | ремень старости | Маркировка - ясно | Многопоточность | да | Стремитесь к кратчайшему времени паузы на переработку |
G1 | Пояс первокурсника + Пояс старшего возраста | алгоритм маркировки-подборки + копирования | Многопоточность | да | JDK1.9 сборщик мусора по умолчанию |
5.2.1 Serial
- Серийный коллекционер: молодое поколение. Старейший коллекционер в разработке. Это однопоточный сборщик, он использует только один ЦП или поток для завершения работы по сборке мусора, и когда он собирает мусор, он должен приостановить все остальные рабочие потоки, пока не закончит сбор.
Функции:
- Сборщик молодого поколения, который использует алгоритм репликации для сбора мусора молодого поколения.
- Для однопоточного сборщика, когда работает сборщик мусора, все остальные потоки перестанут работать.
- Простой и эффективный, подходит для однопроцессорной среды. Один поток не имеет накладных расходов на взаимодействие потоков и, следовательно, имеет самую высокую эффективность сбора отдельных потоков.
Как пользоваться:
//如何设置JVM参数底下会讲解:这里只是列举一部分参数:
设置垃圾收集器:"-XX:+UseSerialGC" --添加该参数来显式的使用改垃圾收集器;
5.2.2 ParNew
- Коллектор ParNew: новое поколение. Многопоточная версия Serial, которая одновременно запускает несколько потоков для сборки мусора.
Функции:
- Коллекционер молодого поколения. Сборщик мусора ParNew — это многопоточная версия сборщика Serial, использующая алгоритм копирования.
- За исключением многопоточности, остальное поведение и характеристики такие же, как у сборщика Serial.
- Только он работает с сборщиком CMS.
- Но в однопроцессорной среде он не лучше, чем сборщик Serail, его лучше использовать с несколькими потоками.
Как пользоваться:
//如何设置JVM参数底下会讲解:这里只是列举一部分参数:
设置垃圾收集器:"-XX:+UseParNewGC" --强制指定使用ParNew;
设置垃圾收集器: "-XX:+UseConcMarkSweepGC" --指定使用CMS后,会默认使用ParNew作为新生代收集器;
设置垃圾收集器参数:"-XX:ParallelGCThreads" --指定垃圾收集的线程数量,ParNew默认开启的收集线程与CPU的数量相同;
5.2.3 Parallel Scavenge
- Параллельный сборщик мусора: молодое поколение. В отличие от ParNew, этот коллектор больше заботится о пропускной способности и максимально быстро выполняет вычислительные задачи.
Функции:
- Коллекционер молодого поколения.
- Используется алгоритм репликации.
- Многопоточная коллекция.
- Отличие от ParNew заключается в том, что целью является высокая пропускная способность (сокращение времени сборки мусора, что позволяет пользовательскому коду работать дольше).
Как пользоваться:
//如何设置JVM参数底下会讲解:这里只是列举一部分参数:
设置垃圾收集器:"-XX:+UseParallelGC" --添加该参数来显式的使用改垃圾收集器;
设置垃圾收集器参数:"-XX:MaxGCPauseMillis" --控制垃圾回收时最大的停顿时间(单位ms)
设置垃圾收集器参数:"-XX:GCTimeRatio" --控制程序运行的吞吐量大小吞吐量大小=代码执行时间/(代码执行时间+gc回收的时间)
设置垃圾收集器参数:"-XX:UseAdaptiveSizePolicy" --内存调优交给虚拟机管理
5.2.4 Serial Old
- Serial Old Collector: версия Serial старого поколения, использующая алгоритм маркировки-сортировки.
Функции:
- Сборщик старого поколения, использующий алгоритм «пометить-разобрать».
- Однопоточная коллекция.
Как пользоваться:
//如何设置JVM参数底下会讲解:这里只是列举一部分参数:
在JDK1.5及之前,与Parallel Scavenge收集器搭配使用,
在JDK1.6后有Parallel Old收集器可搭配。
现在的作为CMS收集器的后备预案,在并发收集发生Concurrent Mode Failure时使用
5.2.5 Parallnel old
- Параллельный старый сборщик, многопоточный: версия Parallel старого поколения, использующая алгоритм маркировки и сопоставления.
Функции:
- На старость.
- Алгоритм "отметка - отделка".
- Многопоточная коллекция.
- Но в однопроцессорной среде он ничем не лучше сборщика Serial Old, и его лучше использовать с несколькими потоками.
Как пользоваться:
//如何设置JVM参数底下会讲解:这里只是列举一部分参数:
设置垃圾收集器:"-XX:+UseParallelOldGC":指定使用Parallel Old收集器;
5.2.6 CMS
- Сборщик CMS: старость. Это сборщик с целью получения кратчайшего времени паузы для восстановления и подходит для интернет-сайтов или серверов систем B/S.
Функции:
- На старости лет используйте метод пометки-очищения для удаления мусора;
- На основе алгоритма "метка - развертка" (операция сжатия не выполняется, фрагментация памяти);
- кратчайшее время переработки;
- Параллельный сбор, низкая пауза;
- Сборщик CMS имеет 3 очевидных недостатка: 1. Он очень чувствителен к ресурсам ЦП, 2. Он не может обрабатывать плавающий мусор и может выйти из строя с «Сбоем в параллельном режиме», 3. Он генерирует много фрагментации памяти
- Потоки сборки мусора и пользовательские потоки могут (в основном) работать одновременно
Как пользоваться:
//如何设置JVM参数底下会讲解:这里只是列举一部分参数:
设置垃圾收集器:"-XX:+UseConcMarkSweepGC":指定使用CMS收集器;
5.2.7 G1
- Коллектор G1: коллектор поколений. Одним из самых передовых достижений в развитии технологии сборщиков на сегодняшний день является сборщик мусора для серверных приложений. Можно сказать, что G1 — это максимально улучшенная версия CMS, которая решает проблему фрагментации памяти CMS и увеличивает объем памяти. Хотя процесс похож на CMS, лежащие в его основе принципы совершенно другие.
Функции:
- Может в полной мере использовать аппаратные преимущества в мульти-процессоре и многоядерных средах;
- Может быть распараллелен для сокращения времени паузы (Stop The World);
- Также возможно одновременное выполнение сборки мусора одновременно с пользовательской программой;
- Коллекция поколений, ассортимент коллекции включает в себя новое поколение и старое поколение
- Он может управлять всей кучей GC (новое поколение и старое поколение) независимо, без необходимости сотрудничать с другими сборщиками;
- Способность по-разному обращаться с объектами разных периодов;
- Сценарий приложения может быть ориентирован на серверные приложения, предназначенные для машин с большим объемом памяти и несколькими процессорами;
- Использование тега - финиширование + алгоритм репликации для переработки мусора
Как пользоваться:
//如何设置JVM参数底下会讲解:这里只是列举一部分参数:
设置垃圾收集器:"-XX:+UseG1GC":指定使用G1收集器;
设置垃圾收集器参数:"-XX:InitiatingHeapOccupancyPercent":当整个Java堆的占用率达到参数值时,开始并发标记阶段;默认为45;
设置垃圾收集器参数:"-XX:MaxGCPauseMillis":为G1设置暂停时间目标,默认值为200毫秒;
设置垃圾收集器参数:"-XX:G1HeapRegionSize":设置每个Region大小,范围1MB到32MB;目标是在最小Java堆时可以拥有约2048个Region
6 Конфигурация параметров JVM
6.1 Краткое описание параметров памяти JVM
#常用的设置
-Xms:初始堆大小,JVM 启动的时候,给定堆空间大小。
-Xmx:最大堆大小,JVM 运行过程中,如果初始堆空间不足的时候,最大可以扩展到多少。
-Xmn:设置堆中年轻代大小。整个堆大小=年轻代大小+年老代大小+持久代大小。
-XX:NewSize=n 设置年轻代初始化大小大小
-XX:MaxNewSize=n 设置年轻代最大值
-XX:NewRatio=n 设置年轻代和年老代的比值。如: -XX:NewRatio=3,表示年轻代与年老代比值为 1:3,年轻代占整个年轻代+年老代和的 1/4
-XX:SurvivorRatio=n 年轻代中 Eden 区与两个 Survivor 区的比值。注意 Survivor 区有两个。8表示两个Survivor :eden=2:8 ,即一个Survivor占年轻代的1/10,默认就为8
-Xss:设置每个线程的堆栈大小。JDK5后每个线程 Java 栈大小为 1M,以前每个线程堆栈大小为 256K。
-XX:ThreadStackSize=n 线程堆栈大小
-XX:PermSize=n 设置持久代初始值
-XX:MaxPermSize=n 设置持久代大小
-XX:MaxTenuringThreshold=n 设置年轻带垃圾对象最大年龄。如果设置为 0 的话,则年轻代对象不经过 Survivor 区,直接进入年老代。
#下面是一些不常用的
-XX:LargePageSizeInBytes=n 设置堆内存的内存页大小
-XX:+UseFastAccessorMethods 优化原始类型的getter方法性能
-XX:+DisableExplicitGC 禁止在运行期显式地调用System.gc(),默认启用
-XX:+AggressiveOpts 是否启用JVM开发团队最新的调优成果。例如编译优化,偏向锁,并行年老代收集等,jdk6纸之后默认启动
-XX:+UseBiasedLocking 是否启用偏向锁,JDK6默认启用
-Xnoclassgc 是否禁用垃圾回收
-XX:+UseThreadPriorities 使用本地线程的优先级,默认启用
等等等......
6.2 Настройки сборщика мусора для JVM
-XX:+UseSerialGC:设置串行收集器,年轻带收集器
-XX:+UseParNewGC:设置年轻代为并行收集。可与 CMS 收集同时使用。JDK5.0 以上,JVM 会根据系统配置自行设置,所以无需再设置此值。
-XX:+UseParallelGC:设置并行收集器,目标是目标是达到可控制的吞吐量
-XX:+UseParallelOldGC:设置并行年老代收集器,JDK6.0 支持对年老代并行收集。
-XX:+UseConcMarkSweepGC:设置年老代并发收集器
-XX:+UseG1GC:设置 G1 收集器,JDK1.9默认垃圾收集器
6.3 Где устанавливаются параметры JVM?
6.3.1 Где IDEA устанавливает параметры JVM
1. Применение единого проекта 2. Глобальная конфигурация
- Найдите каталог bin в каталоге установки IDEA.
- Найдите файл idea.exe.vmoptions
- Откройте файл для редактирования и сохраните.
6.3.2 Где Eclipse устанавливает параметры JVM
1, конфигурация отдельных проектов
Щелкните маленькую стрелку справа от зеленого значка.Нажмите: «Выполнить конфигурации» -> «Аргументы виртуальной машины».
2. Настройте глобальные параметры JVMИзмените файл конфигурации Eclipse в каталоге установки eclipse: файл eclipse.ini
6.3.3 Где пакет war (Tomcat) устанавливает параметры JVM
Война должна быть развернута на Tomcat, то есть изменить параметры JVM Tomcat
1. Под Windows он находится в файле /bin/catalina.bat,Добавьте следующие параметры: JAVA_OPTS (JAVA_OPTS — это переменная, используемая для установки рабочих параметров, связанных с JVM).
set "JAVA_OPTS=-Xms512M -Xmx1024M ...等等等 JVM参数"
2. Linux следует добавить в файл catalina.sh в корзине tomcat
注意:位置要在cygwin=false前
JAVA_OPTS="-Xms512M -Xmx1024M ...等等等 JVM参数"
6.3.4 Где пакеты Jar устанавливают параметры JVM
Пакет Jar прост, обычно проект SpringBoot упакован в пакет Jar для запуска.
#运行时java -jar是直接插入JVM命令就好了
java -Xms1024m -Xmx1024m ...等等等 JVM参数 -jar springboot_app.jar &
6.4 Сводка по настройке
- В практической работе мы можем напрямую сделать начальный размер кучи равным максимальному размеру кучи, Преимущество этого в том, что он может уменьшить количество сборок мусора во время работы программы, тем самым повысив эффективность.
- Чем больше начальное значение кучи и максимальный объем памяти кучи, тем выше пропускная способность. Но сравнивать надо и по фактической памяти собственного компьютера (сервера).
- Лучше использовать параллельный коллектор, потому что параллельный коллектор быстрее и быстрее последовательного. Разумеется, сервер должен быть многопоточным.
- Лучше всего установить соотношение молодого поколения к старому поколению кучи памяти 1:2 или 1:3. По умолчанию 1:2
- Уменьшите коллекцию GC старого поколения. Установить максимальный возраст мусорных объектов в поколении поколения, и не иметь java-объектов с большим объемом непрерывного пространства памяти, т. к. оно уйдет сразу в старое поколение, и если памяти не хватит, будет выполняться GC.
Примечания: На самом деле, самое главное, что сервер лучше, ваше железо не поспевает за ним, а программное обеспечение бесполезноПримечания: GC старое поколение очень медленно, новое поколение хорошоПримечания: Размер кучи JVM по умолчанию составляет около четверти фактической памяти компьютера.
package com.lijie;
public class Test {
public static void main(String[] args) {
System.out.print("最大内存");
System.out.println(Runtime.getRuntime().maxMemory() / 1024.0 / 1024 + "M");
}
}
Мой компьютер имеет 8G RAM
7 загрузчиков классов
7.1 Механизм и процесс загрузки классов
Когда программа активно использует класс, если класс не был загружен в память, JVM инициализирует класс, выполнив три этапа загрузки, подключения и инициализации. Если нет случайностей, JVM выполнит три шага подряд, поэтому иногда эти три шага вместе называются загрузкой класса или инициализацией класса.
JVM выполняет файл класса
1. Загрузить
-
Загрузка относится к чтению файла класса класса в память, преобразованию этих статических данных в структуры данных времени выполнения в области методов и созданию объекта java.lang.Class, представляющего класс в куче в качестве области методов. class data, этот процесс требует участия загрузчика классов.
-
Загрузчики классов Java предоставляются JVM и являются основой для запуска всех программ.Эти загрузчики классов, предоставляемые JVM, часто называют системными загрузчиками классов. Кроме того, разработчики могут создавать свои собственные загрузчики классов, наследуя от базового класса ClassLoader.
-
Загрузчик классов, который может загружать двоичные данные классов из разных источников, таких как: локальные файлы классов, файлы классов пакетов Jar, сетевые файлы классов и т. д.
-
Конечным продуктом загрузки класса является объект класса, расположенный в куче (обратите внимание, что это не объект целевого класса), который инкапсулирует структуру данных класса в области методов и предоставляет пользователю интерфейс для доступа к данным. структура в области методов, то есть отражение Java.
2. Процесс подключения
- Когда класс загружается, система генерирует для него соответствующий объект Class, а затем он вступает в фазу подключения, отвечающую за слияние бинарных данных класса в JRE (имеется в виду слияние бинарного кода java-класса в рабочее состояние JVM) среди них). Классовое соединение можно разделить на следующие три этапа.
-
Проверка. Убедитесь, что загруженная информация о классе соответствует спецификации JVM и что нет проблем с безопасностью. В основном он проверяет, соответствует ли он спецификации формата файла класса и может ли он быть загружен и обработан текущей виртуальной машиной.
-
Подготовка: Этап формального выделения памяти для переменных класса (статических переменных) и установки начального значения переменных класса, эта память будет выделена в области методов
-
Разрешение: символическая ссылка на пул констант виртуальной машины заменена процессом ссылки на байт.
3. Инициализация
-
Фаза инициализации заключается в выполнении конструктора класса
<clinit>
() метод процесса. конструктор класса<clinit>
() Метод заключается в автоматическом сборе класса компилятором.所有类变量的赋值动作和静态语句块(static块)中的语句合并产生,代码从上往下执行。
-
При инициализации класса, если вы обнаружите, что его родительский класс не был инициализирован, вам необходимо сначала инициировать инициализацию его родительского класса.
-
Виртуальная возможность гарантирует класс
<clinit>
() методы должным образом заблокированы и синхронизированы в многопоточной среде
Резюме: Инициализация заключается в присвоении правильных начальных значений статическим переменным класса
7.2 Введение в погрузчик
- Загрузчик классов Bootstrap
- Загрузчик класса расширения
- загрузчик системных классов
- пользовательский загрузчик
1 загрузчик корневого класса (начальный загрузчик классов)
Он используется для загрузки основных классов Java и реализован с помощью собственного кода, не унаследованного от java.lang.ClassLoader (отвечает за загрузку всех классов в jre/lib/rt.jar в $JAVA_HOME, реализуется C++, а не ClassLoader Подкласс). Поскольку загрузчик класса начальной загрузки включает в себя детали локальной реализации виртуальной машины, разработчик не может напрямую получить ссылку на загрузчик класса начальной загрузки, поэтому прямые операции по ссылке не допускаются.
2 Загрузчик классов расширений (загрузчик классов расширений)
Погрузчик класса расширения относится к классу Sun.misc.launcher $ ExtClasslesser, реализованный Sun (который был приобретен Oracle). Он реализован языком Java и является статическим внутренним классом Launcher, который отвечает за загрузку / lib / ext Directory. Или библиотека классов в бите.
3 загрузчик системных классов (загрузчик системных классов)
Известный как системный (также известный как прикладной) загрузчик классов, он отвечает за загрузку параметра -classpath из команды Java, системного свойства java.class.path или переменной CLASSPATH, указанной параметром -classpath при запуске JVM. Программа может получить загрузчик системного класса с помощью статического метода getSystemClassLoader() класса ClassLoader. Если он не указан, все пользовательские загрузчики классов используют этот класс в качестве родителя. Реализованный на языке Java, загрузчик родительского класса — ExtClassLoader. (Виртуальная машина Java принимает режим родительского делегирования, то есть запрос передается родительскому классу для обработки, что является режимом делегирования задачи.)
Загрузчик классов примерно выполняет следующие восемь шагов для загрузки класса:
- Проверяем, загрузился ли этот класс, то есть есть ли этот класс в буфере, если есть, переходим сразу к шагу 8, иначе переходим к шагу 2.
- Если загрузчик родительского класса отсутствует, либо Parent является загрузчиком корневого класса, либо сам является загрузчиком корневого класса, перейдите к шагу 4, если загрузчик родительского класса существует, перейдите к шагу 3.
- Запросите использование загрузчика родительского класса для загрузки целевого класса, если загрузка прошла успешно, перейдите к шагу 8, в противном случае перейдите к шагу 5.
- Запросите использование загрузчика корневого класса для загрузки целевого класса, если загрузка прошла успешно, перейдите к шагу 8, в противном случае перейдите к шагу 7.
- Текущий загрузчик классов пытается найти файл класса, если он найден, он переходит к шагу 6, если не найден, переходит к шагу 7.
- Загрузите класс из файла и в случае успеха перейдите к шагу 8.
- Выдает исключение ClassNotFountException.
- Возвращает соответствующий объект java.lang.Class
7.3 Понимание модели родительской делегации
Механизм делегирования родителей, как он работает, заключается в том, что если загрузчик класса загружает класс, получивший запрос, он не пойдет на их собственную загрузку, а доверит выполнение запроса загрузчику родительского класса, если загрузчик родительского класса также есть загрузчик родительского класса, затем дальнейшее делегирование вверх, за которым следуют рекурсивные запросы, в конечном итоге достигнет вершины загрузчика загрузочного класса, если загрузчик родительского класса может успешно завершить задачу, вернуться, если загрузчик родительского класса не может быть завершена загрузка задач , подзагрузчик попытается загрузить свои, это модель делегирования родителей, в которой каждому сыну лень, каждый раз, когда ты остаешься жить, его отец будет делать, пока мой отец не скажет, что я не могу это сделать, когда сын сам будет найти способ завершить.Преимущество механизма двойного назначения: Преимущество использования режима двойного назначения. Класс Java имеет иерархическую связь со своим загрузчиком класса. С этим уровнем часов он может избежать воспроизведения класс, когда отец Когда этот класс был загружен, нет необходимости загружать снова. Во-вторых, учитывая факторы безопасности, типы, определенные в API-интерфейсе ядра Java, не будут произвольно заменены.Предположим, что класс с именем java.lang.Integer передается по сети, передается загрузчику классов запуска через режим родительского делегирования, а запуск загрузчик классов Класс с таким именем находится в ядре Java API, и обнаружено, что класс был загружен, и java.lang.Integer, переданный сетью, не будет перезагружен, но загруженный Integer.class будет возвращается напрямую, что может предотвратить несанкционированное вмешательство в основные библиотеки API.
7.4 Связь между загрузчиками классов
Далее мы понимаем отношения между загрузчиками классов (не говоря об отношениях наследования), которые можно разделить на следующие четыре пункта
Загрузчик класса запуска, реализованный на C++, не имеет родительского класса.
Расширенный загрузчик классов (ExtClassLoader), реализованный языком Java, загрузчик родительского класса имеет значение null
Загрузчик системного класса (AppClassLoader), реализованный на языке Java, загрузчик родительского класса - ExtClassLoader
Пользовательский загрузчик классов, загрузчик родительского класса должен быть AppClassLoader.
8 инструментов визуализации JVM
8.1 Почему визуализаторы
В процессе разработки крупномасштабных Java-приложений неизбежно возникают такие проблемы, как утечки памяти и узкие места в производительности, такие как незадействованные соединения с файлами, сетями и базами данных, а также неоптимизированные алгоритмы. При непрерывной работе приложения может снижаться эффективность работы всей системы, а в тяжелых случаях возможен сбой системы. Чтобы найти эти скрытые проблемы в программе, инструменты анализа производительности часто используются на более позднем этапе разработки проекта для анализа и оптимизации производительности приложения.
8.2 visualVm
VisualVM — это бесплатный интегрированный инструмент визуализации JDK с несколькими инструментами командной строки, который предоставляет мощную аналитику для анализа производительности и настройки приложений Java. Эти функции включают в себя создание и анализ массивных данных, отслеживание утечек памяти, мониторинг сборщика мусора, памяти и ЦП для выполнения анализа, в то же время он может автоматически выбирать более быструю и легкую технологию, чтобы минимизировать влияние на анализ производительности приложений. за счет повышения точности анализа производительности.
В составе Oracle JDK он находится в папке bin корневого каталога JDK. Сам Visualvm работает на версии JDK6 или более поздней, но может отслеживать приложение JDK1.4 или более поздней версии.
8.2.1 Открыть визуалм
jvisualvm.exe, расположенный в папке bin корневого каталога JDK.Примечание: У меня нет JDK11, не знаю почему, но я нашел этот инструмент на jdk8
8.2.2 Состояние выполнения JVM локального тестового проекта
У меня было несколько локальных процессов, это мои инструменты IDeaЯ запускаю проект SpringBootНачать мониторинг сейчас
8.2.3 Состояние работы JVM проекта тестового сервера
Пропускать::::
8.3 jconsole
JConsole появилась начиная с Java 5. JConsole — это встроенный анализатор производительности Java, который можно запустить из командной строки или в оболочке с графическим интерфейсом. Вы можете легко использовать JConsole (или более продвинутую версию VisualVM) для мониторинга производительности Java-приложений и трассировки кода в Java.
8.3.1 Запуск JConsole
Щелкните jconsole.exe в каталоге jdk/bin для запуска, после чего он автоматически выполнит поиск всех процессов виртуальной машины, запущенных на этой машине. Выберите один из процессов, чтобы начать мониторинг