Понимание внекучной памяти, Unsafe и MaxDirectMemorySize для Java-приложения

Меня смущает то, как JVM контролирует размер кучи, поэтому я хотел бы задать следующие вопросы, чтобы лучше понять это.

  1. Когда люди используют Java Unsafe API для выделения памяти вне кучи в приложении Java, какой параметр jvm можно использовать для управления размером памяти, которая может быть выделена с помощью Unsafe? Это -XX:MaxDirectMemorySize? Есть ли какие-либо другие параметры, которые также можно использовать для управления размером?

  2. В представлении макета памяти JVM есть область, называемая прямой памятью, тогда MaxDirectMemorySize используется для управления размером этой области? и Unsafe выделяется ли память из этой области?

  3. Каков размер вне кучи по умолчанию, если -XX:MaxDirectMemorySize не установлен.

  4. Если Unsafe попытаться выделить больше памяти, чем позволяет JVM (например, больше, чем MaxDirectMemorySize), OOM все равно произойдет?

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
0
242
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

-XX:MaxDirectMemorySize не имеет ничего общего с The Java Unsafe API. Он относится только к прямым байтовым буферам. Подробности можно увидеть в конструкторе DirectByteBuffer.

private static boolean tryReserveMemory(long size, int cap) {

    // -XX:MaxDirectMemorySize limits the total capacity rather than the
    // actual memory usage, which will differ when buffers are page
    // aligned.
    long totalCap;
    while (cap <= maxMemory - (totalCap = totalCapacity.get())) {
        if (totalCapacity.compareAndSet(totalCap, totalCap + cap)) {
            reservedMemory.addAndGet(size);
            count.incrementAndGet();
            return true;
        }
    }

    return false;
}
Ответ принят как подходящий
  1. -XX:MaxDirectMemorySize ограничивает объем памяти, который можно выделить с помощью ByteBuffer.allocateDirect. Хотя allocateDirect использует Unsafe.allocateMemory под капотом, опция MaxDirectMemorySize не влияет на необработанные Unsafe вызовы.

    Unsafe.allocateMemory сводится к функции malloc из стандартной библиотеки. HotSpot JVM не имеет возможности ограничить объем «небезопасной» памяти.

  2. Строго говоря, «прямая память» — это абстракция. Типичная реализация JVM не имеет выделенной области для прямой памяти. Как упоминалось выше, Unsafe.allocateMemory получает память от системного malloc вызова. Кроме того, Direct Buffers подсчитывает выделенную память по лимиту MaxDirectMemorySize.

  3. Если опция MaxDirectMemorySize не установлена, максимальный размер выделяемой прямой памяти ограничивается максимальным размером кучи, точнее, значением Runtime.getRuntime().maxMemory().

  4. Нет, JVM не ограничивает Unsafe.allocateMemory. Операционная система должна контролировать эти выделения.

Да, спасибо @apangin, думаю, теперь я понял Unsafe, DirectMemory намного лучше, спасибо!

Tom 30.04.2024 03:03

Другие вопросы по теме