Разъяснение JVM и GC в одной статье (Часть 1)

Java
Разъяснение JVM и GC в одной статье (Часть 1)

Привет всем, я Сяо Цай, Сяо Цай, который хочет быть Цай Буцаем в интернет-индустрии. Она может быть мягкой или жесткой, как она мягкая, а белая проституция жесткая!
Черт~ Не забудьте поставить мне тройку после прочтения!

"

Эта статья в основном знакомитJVM和GC解析
При необходимости вы можете обратиться к
Если это поможет, не забудьтекак

Творить нелегко, проституция бессмысленна!

1. Система памяти JVM

вобласть методаикучабыть множественным в JVM线程共享, например, статические константы класса хранятся в области методов для совместного использования объектами класса.

стек виртуальных машин,собственный стек методов,счетчик командкаждый线程独立Принадлежит и не используется совместно с другими потоками.

Итак, когда Java создает экземпляр объекта класса через new, с одной стороны, он создаст ссылку на объект в стеке виртуальной машины, с другой стороны, он создаст экземпляр объекта класса в куче, а затем указать ссылку объекта на экземпляр объекта. Ссылки на объекты хранятся в кадре стека, соответствующем каждому методу.

  • 虚拟机栈:Когда каждый метод выполняется в стеке виртуальной машины, создается кадр стека для хранения таблицы локальных переменных, стека операндов, динамической ссылки, выхода метода и другой информации.
  • 本地方法栈:Подобно роли, которую играет стек виртуальной машины, по сравнению со стеком виртуальной машины, обслуживающим методы Java, локальный стек методов обслуживает собственные методы, используемые виртуальной машиной.При выполнении каждого локального метода создается кадр стека для хранения локальных переменных. , Информация о таблицах, стеках операндов, динамических ссылках, выходах методов и т. д.
  • 方法区:Он используется для храненияинформация о классе, константы, статические переменные, код и другие данные, скомпилированные JIT-компилятором, область методов называется постоянной генерацией в JDK1.7 и более ранних версиях, а после JDK1.8 постоянное поколение удалено.
  • 堆:Куча — это область хранения для объектов Java, все новые поля выделяютсяЭкземпляры и массивы объектов Java, размещены в куче, можно использовать кучу Java- Xmsи-XmxДля управления памятью, начиная с версии JDK1.7,постоянный пул времени выполненияПеремещено из области методов в кучу.
  • 程序计数器:Указывает следующую инструкцию байт-кода, которая должна быть выполнена виртуальной машиной Java.

2. JVM после JAVA8

Из рисунка видно, что JVM JAVA8 заменяет постоянное поколение метапространством.

3. Объем GC

В-четвертых, распространенные алгоритмы сборки мусора.

Метод подсчета ссылок:

Реализации JVM обычно не используют этот подход.


недостаток:

  • Счетчик ссылок поддерживается каждый раз при назначении объекта, а сам счетчик имеет определенное потребление;
  • Трудно иметь дело с циклическими ссылками;

Алгоритм копирования:

С точки зрения GC кучу Java можно разделить на:Кайнозой(область Эдема, область «От выжившего» и «Область выжившему») и старость.
Функции:
Алгоритм копирования не приводит к фрагментации памяти, но занимает место. для нового поколения.


Процесс MinorGC (копировать --> пустой --> подкачка):

  1. копировать:(Эден, SurvivorFrom скопировано в SurvivorTo, возраст плюс 1)
    Во-первых, когда область Эдема будет заполнена, будет запущен первый GC, и все еще живые объекты будут скопированы в область SurvivorFrom.Когда область Эдема снова вызовет GC, область Эдема и область From будут отсканированы, в этих двух областях будет выполняться сборка мусора.Объекты, пережившие это восстановление, напрямую копируются в область «Кому» (если возраст какого-либо объекта достиг стандарта старости, он будет скопирован в область старости), а возраст этих объектов увеличивается на 1.
  2. Пустой:(Пустой Эдем, SurvivorFrom)
    Пустые объекты в Eden и SurvivorFrom, т. е. происходит обмен после копирования, кому что пусто - тому.
  3. обмен:(SurvivorTo и SurvivorFrom меняются местами)
    Наконец, SurvivorTo и SurvivorFrom меняются местами, и исходный SurvivorTo становится областью SurvivorFrom для следующего GC.

разметка

Алгоритмы делятся на标记и清除два этапа,Сначала отметьте объекты, подлежащие переработке, а затем равномерно их переработайте.
Функции:
Не занимает лишнего места, но сканирует дважды, требует много времени, склонен к фрагментации, используется на старости лет

сжатие разметки

преимущество:
Нет фрагментации памяти, можно использовать bump
недостаток:
Стоимость перемещения объекта обязательна, для старого поколения
принцип:

Разметка: такая же, как Marker Clear


Сжатие: повторите сканирование и перетащите живые объекты в раздел

5. Определите, подлежит ли объект переработке

подсчет ссылок

В Яве,Ссылки и объекты связаны. Если вы хотите манипулировать объектами, вы должны использовать引用进行.
Итак, очевидно, один из способов - пройти引用计数чтобы определить, может ли объект быть переработан. Проще говоря, это добавление счетчика ссылок к объекту.Всякий раз, когда на него есть ссылка, значение счетчика увеличивается на 1, а всякий раз, когда ссылка становится недействительной, значение счетчика уменьшается на 1.
Объект, значение счетчика которого равно 0, в любое время невозможно использовать снова, тогда этот объект является объектом, пригодным для повторного использования.
недостаток:

Сложно решить проблему циклических ссылок между объектами

Перечислить корневые узлы для анализа достижимости (корневой путь поиска)

так называемыйGC rootsИлиtracing GCизкорневой наборЭто набор ссылок, которые должны быть активны.
Основная идея заключается в использовании рядаGC Rootобъекта в качестве отправной точки, из которой вызываетсяGC RootsОбъектначать поиск вниз.

Если к GC Roots не подключена ни одна цепочка ссылок, это означает, что этот объект недоступен. То есть, учитывая ссылку на коллекцию как на корень, через ссылочное отношение

Что может делать объект GCRoots

  • 虚拟机栈(Область локальных переменных в кадре стека, также называемая таблицей локальных переменных)
  • 方法区中的类静态属性引用的对象
  • 方法区中常量引用的对象
  • 本地方法栈中N(Native方法)引用的对象

6. Типы параметров JVM

1) Стандартные параметры

  • java -version
  • java -help

2) Параметр X

  • java -Xint -version: интерпретировать выполнение
  • java -Xcomp -version: компилировать в собственный код при первом использовании.
  • java -Xmixed: режим смешивания

3) XX параметр

  • Логический тип

-XX:+или-значение атрибута (+: означает открытый,-: указывает близко)
пример:
-XX: +PrintGCDetails: включить печать сведений о коллекции GC
-XX: -PrintGCDetails: отключить печать сведений о коллекции GC.
-XX: +UseSerialGC: включить последовательный сборщик мусора
-XX: -UseSerialGC: отключить серийный сборщик мусора

  • Тип установки КВ

-XX: ключ атрибута = значение атрибута
пример:
-XX: MetaspaceSize = 128m: Установите размер метапространства на 128 м
-XX:MaxTenuringThreshold = 15: Определяет, сколько раз новое поколение должно пройти продвижение GC до максимального порога в старом поколении.

  • jinfo - Просмотр конфигурации запущенной в данный момент программы

формула:jinfo -flagИдентификатор процесса элемента конфигурации
пример:

  1. Проверьте начальный размер кучи:

  2. Посмотреть другие параметры

  3. Посмотрите, какой сборщик мусора используется

两个经典参数

  • -XmsЭквивалентно-XX: InitialHeapSize

  • -XmxЭквивалентно-XX: MaxHeapSize

Семь, просмотрите значение JVM по умолчанию

  • -XX:+PrintFlagsInitial: просмотр начального значения по умолчанию.

    • java -XX: +PrintFlagsInitial -version

    • java -XX: +PrintFlagsInitial

  • -XX:+PrintFlagsFinal: просмотр обновлений модификаций

    • java -XX:+PrintFlagsFinal
    • java -XX:+PrintFlagsFinal -version
    • java -XX:+PrintCommandedLineFlags

Восемь часто используемых параметров конфигурации

Классическая установка корпуса:
-Xms128m -Xmx4096m -Xss1024k -XX:Metaspacesize=512m -XX:+PrintCommandLineFlags -XX:PrintGCDetails -XX:UseSerialGC

  • -Xms

Инициализируйте размер памяти, по умолчанию 1/64 от физической памяти
Эквивалентно-XX:InitialHeapSize

  • -Xmx

Максимально выделенная память, по умолчанию 1/4 от физической памяти
Эквивалентно-XX:MaxHeapSize

  • -Xss

Установите размер одного потока, обычно по умолчанию 5112K~1024K
Эквивалентно-XX:ThreadStackSize

  • -Xmn

Установить размер молодого поколения

  • -XX:MetaspaceSize

Установить размер метапространства

Суть метапространства аналогична постоянному поколению, оба из которых являются реализацией области методов в спецификации JVM, но самая большая разница между метапространством и постоянным поколением заключается в следующем:Метапространство находится не в виртуальной машине, а использует локальную память. Поэтому по умолчаниюРазмер метапространства ограничен только локальной памятью.

  • -XX:+PrintGCdetails

Вывод подробной информации журнала сбора GC

  • -XX:SurvivorRatio

Установить соотношение Эдема и пространства S0/S1 в новом поколении
дефолт:
-XX:SurvivorRatio=8 --> Eden:S0:S1=8:1:1
Исправлять:
-XX:SurvivorRatio=4 --> Eden:S0:S1=4:1:1
Значение SurvivorRatio задает пропорцию площади Эдема, S0/S1 одинаковы.

  • -XX:NewRatio

Установите пропорцию молодого поколения и старого поколения в структуре кучи
дефолт:
-XX:NewRatio=2: На молодое поколение приходится 1, на старое поколение приходится 2, а на молодое поколение приходится 1/3 всей кучи
Исправлять:
-XX:NewRatio=4: На молодое поколение приходится 1, на старое поколение приходится 4, а на молодое поколение приходится 1/5 всей кучи
Значение NewRatio задает пропорцию старого поколения, а оставшийся 1 — для нового поколения.

  • -XX:MaxTenuringThreshold

Установить максимальный возраст мусора
-XX:MaxTenuringThreshold=0: Установите максимальный возраст мусора.

Если установлено значение 0, объекты молодого поколения напрямую входят в старое поколение, не проходя через область Survivor. Для приложений с более старым возрастом эффективность может быть повышена. Если для этого значения установлено большее значение, объекты молодого поколения будут реплицироваться несколько раз в области Survivor, что может увеличить время выживания объектов в молодом поколении и увеличить вероятность повторного использования молодого поколения.

Девять, сильные и слабые


1) Сильные ссылки

  • Когда памяти не хватает, JVM запускает сборку мусора.Даже если произойдет OOM, объект не будет переработан, «смерть не будет собрана»
  • Сильная ссылка — это наша самая распространенная ссылка на объект.Пока существует сильная ссылка, указывающая на объект, также может быть возвращен объект имени таблицы.活着, сборщик мусора не будет трогать такие объекты. Наиболее распространенной в Java является сильная ссылка, присваивающая объект ссылочной переменной, эта ссылочная переменная является строгой ссылкой. Когда на объект ссылается переменная со строгой ссылкой, он находится в достижимом состоянии, и механизм сборки мусора не может его восстановить.Даже если объект никогда не будет использоваться в будущем, JVM не вернет его обратно. Поэтому сильные ссылки — одна из основных причин утечек памяти в Java.
  • Для обычного объекта, если нет другого отношения ссылки, пока область ссылки превышена или соответствующая (строгая) ссылка явно назначается какnull, который обычно считается сборкой мусора (подробности см. в стратегии сборки мусора)
public static void main(String[] args) {
        Object o1 = new Object();   //默认为强引用
        Object o2 = o1;     //引用赋值
        o1 = null;          //置空 让垃圾收集
        System.gc();
        System.out.println(o1);     // null
        System.out.println(o2);     // java.lang.Object@1540e19d
    }

2) Мягкие ссылки

  • Мягкая ссылка — это относительно сильная ссылка, которая немного ослабевает. Его необходимо реализовать с помощью класса java.lang.ref.SoftReference, который может освободить объект от некоторой сборки мусора.
  • системная память充足-> не будет переработан
  • системная память不足-> будут переработаны
  • Мягкие ссылки обычно используются в программах, чувствительных к памяти, таких как кэши, которые используют мягкие ссылки.Когда памяти достаточно, она резервируется, а когда не хватает — перерабатывается.
    public static void main(String[] args) {
        Object o1 = new Object();
        SoftReference softReference = new SoftReference(o1);
        o1 = null;
        System.gc();
        System.out.println(o1);
        System.out.println(softReference.get());
    }

3) Слабые ссылки

  • Необходимо использовать слабые ссылкиjava.lang.ref.WeakReferenceкласс для реализации, он имеет более короткое время жизни, чем мягкие ссылки
  • Для объектов со слабыми ссылками, пока работает механизм сборки мусора, независимо от того, достаточно ли места в памяти JVM, память, занимаемая объектом, будет освобождена.
    public static void main(String[] args) {
        Object o1 = new Object();
        WeakReference weakReference = new WeakReference(o1);
        o1 = null;
        System.gc();
        System.out.println(o1);                     //null
        System.out.println(weakReference.get());    //null
    }

5) Фантомные ссылки

  • требуется фантомная ссылкаjava.lang.ref.PhantomReferenceкласс для реализации.
  • фиктивный, он не определяет время жизни объекта.
  • Если объект содержит фантомную ссылку, то он ничем не отличается от объекта и может быть утилизирован сборщиком мусора в любое время., его нельзя использовать отдельно или для доступа к объекту через него, виртуальная ссылка должна сочетаться с引用队列(ReferenceQueue)используется в комбинации.
  • Основная роль виртуальных ссылок состоит в том, чтобы отслеживать состояние объектов, подвергаемых сборке мусора, и только обеспечивать способ гарантировать, что объекты будут удалены сборщиком мусора.finalizeПозже механизм для выполнения определенных действий.PhantomReferenceизget()Метод всегда возвращает значение null, поэтому доступ к соответствующему ссылочному объекту невозможен. его значениеУказывает, что объект вошел в стадию финализации и может быть перезапущен gc для реализации более гибкой операции перезапуска, чем механизм финализации.
public static void main(String[] args) {
        Object o1 = new Object();
        ReferenceQueue<Object> referenceQueue = new ReferenceQueue<>();
        PhantomReference<Object> phantomReference = new PhantomReference<>(o1,referenceQueue);
        System.out.println(o1);                         //java.lang.Object@1540e19d
        System.out.println(phantomReference.get());     //null
        System.out.println(referenceQueue.poll());      //null
    }

расширять: Применимые сценарии для слабых ссылок

Если есть ссылка, которая должна прочитать большое количество локальных изображений
Существует проблема:

  1. Если образ будет считываться с жесткого диска каждый раз при его чтении, это серьезно повлияет на производительность.
  2. Если все это загружается в память одновременно, это может вызвать переполнение памяти.

Решения:
HashMap используется для сохранения отношения сопоставления между путем к изображению и мягкой ссылкой, связанной с соответствующим объектом изображения.Когда памяти недостаточно, JVM автоматически восстанавливает пространство, занимаемое этими кэшированными объектами изображения, таким образом эффективно избегая проблема с ООМ.
Map<String,SoftReference> imgMap = new HashMap<String,SoftReference>()

WeakHashMap:

public static void main(String[] args) {
        WeakHashMap<Integer,String> weakHashMap = new WeakHashMap<>();
        Integer key = new Integer(1);
        weakHashMap.put(key,"测试1");
        System.out.println(weakHashMap);    //{1=测试1}
        key=null;
        System.out.println(weakHashMap);    //{1=测试1}
        System.gc();
        System.out.println(weakHashMap+"\t"+weakHashMap.size());    //{} 0
    }
看完不赞,都是坏蛋
Не понравилось после прочтения, все хреново
"

Если вы будете усердно работать сегодня, завтра вы сможете сказать на одну вещь меньше, чтобы попросить о помощи!

Я Сяо Цай, человек, который учится у вас. 💋