Введение
Escape-анализ Мы уже говорили об оптимизации производительности JVM в JDK 14. Результатом escape-анализа является то, что JVM будет размещать объекты в стеке, тем самым повышая эффективность. Если мы находимся в многопоточной среде, как повысить эффективность выделения памяти? Приходите и изучите технологию TLAB вместе с младшей сестрой.
Анализ экранирования и выделение стека
Младшая младшая сестра: Старший брат Ф., все раньше говорили, что объекты располагаются в куче, и тогда я им поверила. В последний раз, когда вы действительно сказали, что можете размещать объекты в стеке, это действительно подрывает мое обычное понимание.
Платон сказал: Мысль всегда правит вселенной. Пока разум не скользит, решений всегда больше, чем трудностей. То, что другие говорят вам, — это самые основные, самые общие ситуации. И брат, то, что я тебе сказал, это особая ситуация с оптимизацией.
Младшая сестра: Брат Ф., кажется, JVM действительно провела большую оптимизацию для повышения скорости работы.
Да, Java с самого начала критиковали за медленную скорость, а теперь скорость выполнения догоняет язык C. Эти оптимизации во время выполнения необходимы. Помните, что мы говорили ранее об анализе побега?
Мусс: F брат, это я знаю, если объект аллоцирован внутри, и нет многопоточного доступа, то этот объект реально может быть виден как локальный объект, такие объекты только создаются.Метод в этом рычаге может быть виден, поэтому его можно напрямую назначить в пространстве стека.
Правильно, потому что объекты размещаются в стеке независимо от синхронизации, это, безусловно, будет более быстрой скоростью выполнения, и это причина, по которой JVM представит размещение в стеке.
Возьмем еще один интуитивный пример. Чтобы собрать автомобиль на заводе, в процессе buildCar нужно сначала создать объект Car, а затем нажимать на него колеса.
public static void main(String[] args) {
buildCar();
}
public static void buildCar() {
Wheel whell = new Wheel(); //分配轮子
Car car = new Car(); //分配车子
car.setWheel(whell);
}
}
class Wheel {}
class Car {
private Wheel whell;
public void setWheel(Wheel whell) {
this.whell = whell;
}
}
Рассмотрим приведенную выше ситуацию: если предположить, что мастерская — это робот, собирающий автомобиль, то объекты Car и Wheel, созданные вышеописанным методом, будут доступны только этому роботу, а другие роботы вообще не будут использовать этот автомобиль. . Тогда объект практически невидим для других роботов. Таким образом, мы можем разместить этот объект не в публичном пространстве, а в приватном пространстве стека.
Еще одна функция анализа побегов — укрупнение блокировок. Точно так же в однопоточной среде блокировки не нужны, и их можно оптимизировать.
Введение в TLAB
Младшая сестра: Брат Ф., я думаю, что анализ выхода очень хороший, и распределение в стеке тоже хорошее. Поскольку эти две технологии такие мощные, зачем использовать TLAB?
Во-первых, это два разных понятия, полное название TLAB — Thread-Local Allocation Buffers. Thread-Local знают все, это локальная переменная потока. TLAB — это локальное пространство размещения потока.
Escape-анализ и выделение стека предназначены только для однопоточной среды, а в многопоточной среде неизбежно, что несколько потоков будут одновременно распределять объекты в пространстве кучи.
Как поступить в этой ситуации, чтобы повысить производительность?
Младшая сестра: Ничего себе, несколько потоков конкурируют за общие ресурсы, разве это не типичная проблема с блокировкой и синхронизацией?
Блокировка и синхронизация должны гарантировать, что весь ресурс может быть доступен только одному потоку за раз.В нашей текущей ситуации нам нужно разделить определенную область для потоков в ресурсе. Эта операция не требует полной синхронизации, потому что пространство кучи достаточно большое, мы можем разделить небольшую область в этом пространстве, и разделить кусок для каждого потока. Разве это не решает проблему синхронизации? Это также можно назвать пространством для времени.
Подробное объяснение TLAB
Младшая сестра, вы еще помните два основных момента технологии генерации кучи? О, 1 пространство Эдема и 2 пространства Сувивора?
Young Gen разделен на 1 Eden Space и 2 Suvivor Spaces. Когда объект только что создан, он помещается в пространство Эдема. Во время сборки мусора сканируются Eden Space и Survivor Space. Если во время сборки мусора окажется, что объект в Eden Space все еще действителен, он будет скопирован в другое Survivor Space.
Таким образом, непрерывное сканирование и, наконец, после многократного сканирования обнаруживается, что все еще действительные объекты будут помещены в Old Gen, что указывает на то, что их жизненный цикл относительно длинный, что может сократить время сборки мусора.
Поскольку TLAB фокусируется на вновь выделенных объектах, TLAB размещается в интервале Эдема, и из рисунка видно, что TLAB представляет собой непрерывное пространство один за другим.
Эти смежные пространства затем выделяются каждому потоку для использования.
Поскольку каждый поток имеет свое собственное независимое пространство, концепция синхронизации здесь не задействована. TLAB включен по умолчанию, вы можете сделать это:
-XX:-UseTLAB
чтобы закрыть его.
Установите размер пространства TLAB
Младшая сестра, старший брат Ф., является ли размер этого TLAB размером системы по умолчанию? Можем ли мы управлять его размером вручную?
Чтобы решить эту проблему, нам нужно взглянуть на реализацию JVM на C++, которая называется threadLocalAllocBuffer.cpp:
Как видно из приведенного выше кода, если TLAB установлен (по умолчанию 0), то размер TLAB является наименьшим из определенного TLABSize, деленного на HeapWordSize и max_size().
HeapWordSize — это размер слова в куче, я думаю, он = 8. Не спрашивайте почему, на самом деле я тоже догадался.Если кто знает ответ, можете оставить сообщение и сообщить мне.
Размер TLAB может быть определен:
-XX:TLABSize
устанавливать.
Если TLAB не задан, то размер TLAB равен среднему значению выделенных потоков.
Минимальное значение TLAB может быть получено следующим образом:
-XX:MinTLABSize
устанавливать.
по умолчанию:
-XX:ResizeTLAB
Переключатель изменения размера включен по умолчанию, поэтому JVM может регулировать размер пространства TLAB.
Размещение крупных объектов в TLAB
Младшая сестра: Брат Ф., я подумала о вопросе: поскольку TLAB имеет размер, если в потоке определен очень большой объект, и TLAB не может поместиться, что мне делать?
Хороший вопрос, в этом случае есть две возможности, предположим, что размер текущего TLAB составляет 100 КБ:
Первая возможность:
На данный момент в TLAB использовано 20К, а есть еще размер 80К. В это время мы создали объект размером 90К. Теперь объект размером 90К не может быть помещен в TLAB. В это время нам нужно выделить этот объект непосредственно в пространстве кучи Эта операция на самом деле Вышеупомянутая операция является вырожденной операцией, официально называемой медленным выделением.
Вторая возможность:
На данный момент TLAB используется 90К, а осталось 10К.В это время мы создаем объект размером 15К.
В это время необходимо рассмотреть, выполняется ли еще операция медленного выделения.
Поскольку TLAB почти израсходован, чтобы гарантировать, что новый объект все еще может иметь доступный TLAB, JVM может попытаться удалить текущий TLAB, затем выделить новое пространство TLAB и поместить в него 15 000 объектов.
JVM имеет переключатель под названием:
-XX:TLABWasteTargetPercent=N
Значение по умолчанию этого переключателя равно 1. Указывает, что если размер нового выделенного объекта превышает установленные 100 %, будет выполняться медленное выделение. В противном случае выделяется новое пространство TLAB.
В то же время JVM также определяет переключатель:
-XX:TLABWasteIncrement=N
Чтобы предотвратить слишком много медленных выделений, JVM определяет этот переключатель (значение по умолчанию — 4).Например, предельное значение первого медленного выделения составляет 1%, тогда предельное значение следующего медленного выделения равно %1+. 4%=5%.
Отходы в пространстве TLAB
Младшая сестра: Брат Ф., если новое выделенное пространство TLAB используется, что мне делать с неиспользуемым пространством в старом TLAB?
Это называется TLAB Waste. Поскольку объекты больше не размещаются в старом пространстве TLAB, оставшееся пространство тратится впустую.
Суммировать
В этой статье описывается анализ побегов и использование TLAB. Надеюсь, всем понравится.
Автор статьи: о программе flydean
Ссылка на эту статью:Woohoo.Floyd Press.com/JVM-ESCAP…
Источник этой статьи: блог flydean
Добро пожаловать, обратите внимание на мой публичный номер: вас ждут самые интересные вещи о программе!