Как выделить память java

Обновлено: 02.07.2024

Управление памятью — это процесс выделения новых объектов и удаления неиспользуемых объектов, чтобы освободить место для этих новых объектов. В этом разделе представлены некоторые основные концепции управления памятью и объясняются основы выделения объектов и сборки мусора в JVM Oracle JRockit. Рассматриваются следующие темы:

Информацию о том, как использовать параметры командной строки для настройки системы управления памятью, см. в разделе Настройка системы управления памятью.

Куча и питомник

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

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

Куча иногда делится на две области (или поколения), которые называются питомник (или молодое пространство) и старое пробел. Детская — это часть кучи, зарезервированная для размещения новых объектов. Когда питомник заполняется, сбор мусора осуществляется путем запуска специальной молодой коллекции, где все объекты, достаточно долго прожившие в питомнике, перемещаются (перемещаются) в старое пространство , тем самым освобождая детскую для размещения большего количества объектов. Когда старое пространство заполняется мусором, в нем собирается процесс, называемый старой коллекцией.

Смысл питомника в том, что большинство объектов временны и недолговечны. Молодая коллекция разработана таким образом, чтобы быстро находить недавно выделенные объекты, которые еще живы, и перемещать их из детской. Как правило, молодая коллекция освобождает заданный объем памяти намного быстрее, чем старая коллекция или сборка мусора из кучи с одним поколением (куча без питомника).

В R27.2.0 и более поздних версиях часть питомника зарезервирована как область хранения. Область хранения содержит самые последние выделенные объекты в питомнике и не очищается от мусора до следующей молодой коллекции. Это предотвращает повышение уровня объектов только потому, что они были выделены прямо перед запуском молодой коллекции.

Распределение объектов

Во время выделения объектов JVM JRockit различает маленькие и большие объекты. Ограничение, когда объект считается большим, зависит от версии JVM, размера кучи, стратегии сборки мусора и используемой платформы, но обычно составляет от 2 до 128 КБ. Дополнительные сведения см. в документации по параметрам -XXtlaSize и -XXlargeObjectLimit.

Небольшие объекты размещаются в локальных областях потока (TLA). Локальные области потока — это свободные фрагменты, зарезервированные из кучи и предоставленные потоку Java для монопольного использования. Затем поток может размещать объекты в своем TLA без синхронизации с другими потоками. Когда TLA заполняется, поток просто запрашивает новый TLA. TLA резервируются из питомника, если он существует, в противном случае они резервируются где угодно в куче.

Большие объекты, которые не помещаются в TLA, размещаются непосредственно в куче. При использовании детской крупные объекты размещаются непосредственно в старом пространстве. Выделение больших объектов требует большей синхронизации между потоками Java, хотя JVM JRockit использует систему кешей свободных фрагментов разного размера, чтобы уменьшить потребность в синхронизации и повысить скорость выделения.

Сборка мусора

Сборка мусора — это процесс освобождения места в куче или питомнике для размещения новых объектов. В этом разделе описывается сборка мусора в JRockit JVM.

Модель маркировки и развертки

Виртуальная машина JRockit JVM использует модель сборки мусора пометить и очистить для выполнения сборки мусора всей кучи. Сборка мусора с маркировкой и очисткой состоит из двух этапов: этапа маркировки и этапа этапа очистки.

На этапе пометки все объекты, доступные из потоков Java, собственные дескрипторы и другие корневые источники, помечаются как активные, а также объекты, доступные из этих объектов и т. д. Этот процесс идентифицирует и помечает все объекты, которые все еще используются, а остальные можно считать мусором.

Во время фазы сканирования куча просматривается, чтобы найти промежутки между живыми объектами. Эти промежутки записываются в свободный список и становятся доступными для нового размещения объектов.

JRockit JVM использует две улучшенные версии модели маркировки и развертки. Одна из них в основном параллельная маркировка и развертка, а другая — параллельная маркировка и развертка.Вы также можете комбинировать две стратегии, используя, например, параллельную маркировку и параллельную развертку.

В основном одновременная маркировка и очистка

Стратегия в основном параллельной пометки и очистки (часто называемая просто одновременной сборкой мусора) позволяет потокам Java продолжать работу во время больших частей сборки мусора. Однако потоки должны быть остановлены несколько раз для синхронизации.

Этап маркировки, в основном параллельный, разделен на четыре части:

    Исходная маркировка, при которой идентифицируется корневой набор живых объектов. Это делается, когда потоки Java приостановлены. Параллельная маркировка, когда ссылки из корневого набора используются для поиска и маркировки остальных живых объектов в куче. Это делается во время выполнения потоков Java. Предварительная очистка, при которой идентифицируются изменения в куче на этапе параллельной маркировки, а также обнаруживаются и помечаются любые дополнительные живые объекты. Это делается во время выполнения потоков Java. Окончательная маркировка, при которой выявляются изменения на этапе предварительной очистки, а также обнаруживаются и отмечаются любые дополнительные живые объекты. Это делается, когда потоки Java приостановлены.

Фаза одновременных проверок состоит из четырех частей:

    Подметание одной половины кучи. Это делается во время работы потоков Java, и им разрешено размещать объекты в той части кучи, которая в данный момент не очищается. Небольшая пауза для смены половинок. Подметание другой половины кучи. Это делается во время работы потоков Java, и им разрешено размещать объекты в той части кучи, которая была очищена первой. Небольшая пауза для синхронизации и записи статистики.

Параллельная маркировка и развертка

Стратегия параллельной маркировки и очистки (также называемая параллельным сборщиком мусора) использует все доступные ЦП в системе для максимально быстрой сборки мусора. Все потоки Java приостанавливаются во время всей параллельной сборки мусора.

Сборка мусора поколений

Питомник, если он существует, представляет собой сбор мусора специальной сборкой мусора, называемой молодой коллекцией. Стратегия сборки мусора, использующая питомник, называется общей стратегией сборки мусора или просто последовательной сборкой мусора.

Молодой сборщик, используемый в JVM JRockit, идентифицирует и продвигает все живые объекты в питомнике, которые находятся за пределами области хранения, в старое пространство. Эта работа выполняется параллельно с использованием всех доступных процессоров. Потоки Java приостанавливаются во время всей молодой коллекции.

Режимы динамической и статической сборки мусора

По умолчанию JRockit JVM использует режим динамической сборки мусора, который автоматически выбирает используемую стратегию сборки мусора с целью оптимизации пропускной способности приложения. Вы также можете выбрать один из двух других режимов динамической сборки мусора или выбрать стратегию сборки мусора статически. Доступны следующие динамические режимы:

    пропускная способность, которая оптимизирует сборщик мусора для максимальной пропускной способности приложения. Это режим "по умолчанию". pausetime , который оптимизирует сборщик мусора для коротких и равномерных пауз. deterministic , оптимизирующий сборщик мусора для очень коротких и детерминированных пауз. Этот режим доступен только в составе Oracle JRockit Real Time.
    singlepar , который представляет собой параллельный сборщик мусора с одним поколением (то же, что и parallel ) genpar , который представляет собой параллельный сборщик мусора с двумя поколениями singlecon , который представляет собой в основном параллельный сборщик мусора с одним поколением gencon , который представляет собой в основном параллельный сборщик мусора с двумя поколениями коллекционер

Дополнительную информацию о том, как выбрать лучший режим или стратегию для вашего приложения, см. в разделе Выбор и настройка сборщика мусора.

Сжатие

Объекты, размещенные рядом друг с другом, не обязательно станут недоступными ("умрут") одновременно. Это означает, что куча может быть фрагментирована после сборки мусора, так что свободного места в куче много, но мало, что делает выделение больших объектов трудным или даже невозможным. Свободное пространство, размер которого меньше минимального размера локальной области потока (TLA), вообще нельзя использовать, и сборщик мусора отбрасывает его как темную материю до тех пор, пока будущая сборка мусора не освободит достаточно места рядом с ним для создайте место, достаточно большое для TLA.

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

Сжатие выполняется в начале или во время фазы очистки и во время приостановки всех потоков Java.

Информацию о том, как настроить сжатие, см. в разделе Настройка сжатия памяти.

Внешнее и внутреннее уплотнение

JRockit JVM использует два метода сжатия: внешнее уплотнение и внутреннее уплотнение. Внешнее уплотнение перемещает (эвакуирует) объекты в пределах области уплотнения в свободные позиции за пределами области уплотнения и как можно ниже в куче. Внутреннее уплотнение перемещает объекты в пределах области уплотнения как можно ниже в области уплотнения, тем самым сближая их друг с другом.

JVM выбирает метод уплотнения в зависимости от текущего режима сборки мусора и положения области уплотнения. Внешнее уплотнение обычно используется в верхней части кучи, а внутреннее — в нижней части, где плотность объектов выше.

Схемы скользящего окна

Положение области уплотнения изменяется при каждой сборке мусора, используя одно или два скользящих окна для определения следующей позиции. Каждое скользящее окно перемещается на ступеньку вверх или вниз в куче при каждой сборке мусора, пока не достигнет другого конца кучи или не встретится со скользящим окном, которое движется в противоположном направлении, и начинается сначала. Таким образом, вся куча в конечном итоге проходится сжатием снова и снова.

Размер области уплотнения

Размер области уплотнения зависит от используемого режима сборки мусора. В пропускном режиме размер зоны уплотнения является статическим, в то время как во всех других режимах, включая статический, размер зоны уплотнения регулируется в зависимости от положения зоны уплотнения с целью поддержания одинакового времени уплотнения на протяжении всего цикла. Время уплотнения зависит от количества перемещенных объектов и количества ссылок на эти объекты. Таким образом, область уплотнения будет меньше в тех частях кучи, где плотность объектов высока или где велико количество ссылок на объекты в области. Обычно плотность объектов выше в нижней части кучи, чем в верхней части кучи, за исключением самого верха, где находятся самые последние выделенные объекты. Таким образом, области уплотнения обычно меньше в нижней части кучи, чем в верхней половине кучи.

Стек в Java — это раздел памяти, содержащий методы, локальные переменные и ссылочные переменные. Память стека всегда используется в порядке «последний пришел – первый обслужен». Локальные переменные создаются в стеке.

Что такое динамическая память?

Куча — это раздел памяти, который содержит объекты и может также содержать ссылочные переменные. Переменные экземпляра создаются в куче

Распределение памяти в Java

Выделение памяти в Java — это процесс, в котором разделы виртуальной памяти выделяются в программе для хранения переменных и экземпляров структур и классов. Однако память не выделяется объекту при объявлении, а создается только ссылка. Для выделения памяти объекта используется метод new(), поэтому объекту всегда выделяется память в куче.

Распределение памяти Java разделено на следующие разделы:

Это разделение памяти необходимо для ее эффективного управления.

  • Раздел кода содержит ваш байт-код.
  • Раздел памяти Stack содержит методы, локальные переменные и ссылочные переменные.
  • Раздел Heap содержит объекты (также может содержать ссылочные переменные).
  • Статический раздел содержит статические данные/методы.

Разница между локальной переменной и переменной экземпляра

Переменная экземпляра объявляется внутри класса, но не внутри метода

Локальная переменная объявляется внутри метода, включая аргументы метода.

Разница между стеком и кучей

Нажмите здесь, если видео недоступно

Давайте рассмотрим пример, чтобы лучше понять это.

Учтите, что ваш основной метод вызывает метод m1

В стеке java кадр будет создан из метода m1.

Java Stack and Heap

Переменная X в m1 также будет создана во фрейме для m1 в стеке. (См. изображение ниже).

Java Stack and Heap

Метод m1 вызывает метод m2. В стеке java создается новый фрейм для m2 поверх фрейма m1.

Java Stack and Heap

Java Stack and Heap

Переменные b и c также будут созданы во фрейме m2 в стеке.

Java Stack and Heap

Тот же метод m2 вызывает метод m3. Снова наверху стека создается кадр m3 (см. изображение ниже).

Java Stack and Heap

Java Stack and Heap

Теперь предположим, что наш метод m3 создает объект для класса «Учетная запись», который имеет две переменные экземпляра: int p и int q.

Вот код метода m3

Выражение new Account() создаст объект account в куче.

Java Stack and Heap

Ссылочная переменная «ref» будет создана в стеке java.

Java Stack and Heap

Операция присваивания «=» создаст ссылочную переменную, указывающую на объект в куче.

Java Stack and Heap

После завершения выполнения метода. Поток управления вернется к вызывающему методу. В данном случае это метод m2.

Java Stack and Heap

Стек из метода m3 будет очищен.

Java Stack and Heap

Поскольку ссылочная переменная больше не будет указывать на объект в куче, она будет допущена к сборке мусора.

Java Stack and Heap

После завершения выполнения метода m2. Он будет удален из стека, а все его переменные будут сброшены и больше не будут доступны для использования.

Аналогично для метода m1.

В конечном итоге поток управления вернется к начальной точке программы. Обычно это «основной» метод.

Что, если Object имеет ссылку в качестве переменной экземпляра?

В этом случае ссылочная переменная «child» будет создана в куче, которая, в свою очередь, будет указывать на свой объект, что-то вроде схемы, показанной ниже.

Менеджер по разработке программного обеспечения @ upGrad. Увлечен созданием крупномасштабных веб-приложений с восхитительным опытом. Стремление превратить инженеров в лидеров.

Выделение памяти в Java – это процесс, в котором компьютерные программы и службы выделяются в виде виртуальных пространств памяти. Виртуальная машина Java делит память на Stack и Heap Memory. Для виртуальной машины Java выполнение приложения с максимальным потенциалом может происходить из памяти стека и кучи. Каждый раз, когда объявляется новая переменная или объект, память выделяет память, предназначенную для таких операций.

Оглавление

Память стека

Выделение стандартной памяти в java используется для статической памяти и выполнения потоков. Значения, содержащиеся в этой памяти, являются временными и ограничены определенными методами, поскольку на них продолжают ссылаться в режиме «последним пришел — первым вышел».

Как только вызывается память и в памяти стека создается новый блок, память стека затем содержит примитивные значения и ссылки до тех пор, пока метод не будет продолжаться. После его окончания блок сбрасывается и доступен для нового процесса. Как правило, общий размер памяти стека незначителен по сравнению с памятью кучи.

Характеристики памяти стека

Основываясь на различных разделах распределения памяти в виртуальной машине Java (JVM), вот некоторые отдельные особенности стековой памяти:

  • Память стека может увеличиваться или уменьшаться по мере вызова и возврата любых новых методов.
  • Любая переменная в стеке может работать, пока существует область действия метода.
  • Он получает автоматическое выделение и освобождение по мере выполнения метода.
  • В случае переполнения памяти срабатывает ошибка java.lang.StackOverFlowError.
  • Доступ к ней быстрее по сравнению с динамической памятью.

Методы, используемые при выделении памяти стека в Java

  • Проталкивание объекта (элемент объекта): здесь элемент перемещается на вершину стека.
  • Объект pop(): любой элемент, расположенный в верхней части стека, сбрасывается и возвращается. В случае, если стек пуст во время вызова pop(), возникает исключение — EmptyStackException.
  • Object peek(): здесь возвращается верхний элемент, но он не подвергается очистке.
  • Boolean empty(): если в стеке цикла нет верхнего значения, функция возвращает 1 (истина), в противном случае 0 (ложь).
  • В поиске (элемент объекта): используется, чтобы понять, присутствует ли объект в стеке. В случае, если значение найдено, функция возвращает расположение элемента с вершины стека, в противном случае возвращает -1.


Пространство кучи Java

Пространство кучи Java, в основном используемое средой выполнения Java, вступает в игру каждый раз, когда объект создается и размещается в нем. Дискретная функция, такая как сборка мусора, продолжает сбрасывать память, используемую предыдущими объектами, которые не содержат ссылок. Поскольку объект, созданный в Heap Space, может иметь свободный доступ через приложение.

Распределение памяти в Java разделено на части, а именно: куча, стек, код и статика.

Характеристики динамической памяти Java

  • Доступно из сложной техники управления памятью, включая молодое поколение, старое или постоянное поколение и постоянное поколение.
  • При заполнении динамической памяти возвращается ошибка java.lang.OutOfMemoryError.
  • Доступ к этой памяти сравнительно медленнее, чем к памяти стека.
  • Она не подвергается автоматическому освобождению и требует функции, аналогичной сборщику мусора, для удаления посторонних объектов, чтобы память работала в оптимальном режиме.

Пример выделения памяти в стеке и куче в Java:



Пространство кучи и память стека: фундаментальные различия

< td>Здесь за исключением java.lang .OutOfMemoryError возникает в случае переполнения памяти. < /tr> < /tr>
Память кучи Память стека
Все части приложения обращаются к памяти кучи. Выполнение памяти стека ограничено одним потоком.
Всякий раз, когда создается объект, он сохраняется в пространстве кучи. Память стека содержит только его ссылку и локальные примитивные переменные.
Объекты здесь доступны глобально через приложение. Другие потоки не могут получить доступ к объектам памяти стека. .
Здесь память определяется в соответствии с молодым и старым поколениями. Управление памятью происходит по принципу «последним пришел – первым вышел».
Память остается в соответствии с объемом приложения. Память является временной.
Методы Например, XMX и XMS JVM используются для определения оптимального размера динамической памяти. Для стековой памяти он определяется методом -XSS.
Здесь ошибка java.lang.StackOverFlowError возникает в случае переполнения памяти.
Размер больше, но требует больше времени для обработки по сравнению со стековой памятью. Размер меньше, но выполняется быстрее для плавной операции LIFO.

Обучайтесь онлайн-курсам по программному обеспечению в лучших университетах мира. Участвуйте в программах Executive PG, Advanced Certificate Programs или Master Programs, чтобы ускорить свою карьеру.

Заключение

Распределение памяти в Java происходит двумя способами, в основном, в стеке и в куче. Мы надеемся, что это помогло вам понять процесс всего этого.

Если вам интересно узнать больше о разработке программного обеспечения с полным стеком, ознакомьтесь с программой upGrad & IIIT-B Executive PG по разработке программного обеспечения с полным стеком, которая предназначена для работающих профессионалов и предлагает более 500 часов серьезного обучения, 9 + проекты и задания, статус выпускника IIIT-B, практические практические проекты и помощь в трудоустройстве в ведущих фирмах.

Как происходит управление памятью в Java?

Виртуальная машина Java (JVM) — это компьютерная программа, используемая для запуска программ, написанных на языке программирования Java. Это делает процесс использования управления памятью эффективным. Кроме того, он разработан таким образом, чтобы даже в случае сбоя операционной системы программа, работающая на JVM, не пострадала.Управление памятью означает управление каждой частью памяти (ОЗУ) в компьютерной системе. JVM отслеживает выделение и освобождение памяти при необходимости. Как только программа загружается в память, JVM выделяет для нее место в памяти. Этот процесс называется кучей. Куча — это общее пространство памяти для многих частей приложения.

Что такое сборка мусора в Java?

Виртуальная машина Java (JVM) использует подсчет ссылок для отслеживания количества объектов Java. Прежде чем какой-либо объект может быть собран, количество ссылок на этот объект должно достичь нуля. Пользовательская программа может явно удалять объекты, вызывая метод finalize(). Finalize — это статический метод класса Object, который вызывается сборщиком мусора (GC). Метод Finalize освободит все ресурсы объекта, прежде чем сборщик мусора позаботится об этом объекте. Сборщик мусора — это процесс очистки ненужных объектов. Процесс сборщика мусора будет запущен, когда система времени выполнения Java обнаружит, что куча Java почти заполнена. Каждый объект имеет растровое изображение в JVM. Растровое изображение устанавливается для каждого объекта, чтобы отслеживать, использовался ли он или нет. Когда растровое изображение установлено на 0, GC позаботится об этом объекте.

Каковы особенности языка программирования Java?

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

В этом руководстве мы рассмотрим эти модели памяти. Во-первых, мы рассмотрим их ключевые особенности. Затем мы узнаем, как они хранятся в оперативной памяти и где их использовать. Наконец, мы обсудим основные различия между ними.

2. Память стека в Java

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

Доступ к этой памяти осуществляется в порядке "последним поступил - первым обслужен" (LIFO). Всякий раз, когда мы вызываем новый метод, в верхней части стека создается новый блок, который содержит значения, характерные для этого метода, такие как примитивные переменные и ссылки на объекты.

Когда метод завершает выполнение, соответствующий кадр стека сбрасывается, поток возвращается к вызывающему методу, и освобождается место для следующего метода.

2.1. Ключевые особенности памяти стека

Некоторые другие особенности стековой памяти включают:

  • Он увеличивается и уменьшается по мере вызова и возврата новых методов соответственно.
  • Переменные внутри стека существуют только до тех пор, пока работает создавший их метод.
  • Он автоматически выделяется и освобождается, когда метод завершает выполнение.
  • Если эта память заполнена, Java выдает java.lang.StackOverFlowError.
  • Доступ к этой памяти быстрее по сравнению с динамической памятью.
  • Эта память является потокобезопасной, поскольку каждый поток работает в своем собственном стеке.

3. Пространство кучи в Java

Пространство кучи используется для динамического выделения памяти для объектов Java и классов JRE во время выполнения. Новые объекты всегда создаются в куче, а ссылки на эти объекты хранятся в памяти стека.

Эти объекты имеют глобальный доступ, и мы можем получить к ним доступ из любой точки приложения.

  1. Молодое поколение — здесь размещаются и стареют все новые объекты. При заполнении происходит небольшая сборка мусора.
  2. Старое поколение или постоянная генерация — здесь хранятся долго сохраняющиеся объекты. Когда объекты хранятся в молодом поколении, устанавливается пороговое значение возраста объекта, и при достижении этого порога объект перемещается в старое поколение.
  3. Постоянная генерация — состоит из метаданных JVM для классов среды выполнения и методов приложения.

Эти различные части также обсуждаются в статье Разница между JVM, JRE и JDK.

Мы всегда можем управлять размером динамической памяти в соответствии с нашими требованиями. Для получения дополнительной информации посетите эту связанную статью Baeldung.

3.1. Ключевые особенности динамической памяти Java

Некоторые другие особенности пространства кучи включают:

  • Доступ к нему осуществляется с помощью сложных методов управления памятью, включающих молодое поколение, старое или постоянное поколение и постоянное поколение.
  • Если место в куче заполнено, Java выдает java.lang.OutOfMemoryError.
  • Доступ к этой памяти сравнительно медленнее, чем к памяти стека.
  • Эта память, в отличие от стека, не освобождается автоматически. Требуется сборщик мусора, чтобы освободить неиспользуемые объекты, чтобы сохранить эффективность использования памяти.
  • В отличие от стека, куча не является потокобезопасной и требует защиты путем правильной синхронизации кода.

4. Пример

Давайте проанализируем это шаг за шагом:

Давайте посмотрим на это распределение на диаграмме ниже:


5. Резюме

Прежде чем мы закончим эту статью, давайте кратко суммируем различия между памятью стека и пространством кучи:

< td>Порядок < /tbody>
Параметр Память стека Пространство кучи
Приложение Стек используется частями, по одному во время выполнения потока Все приложение использует пространство кучи во время выполнения
Размер Стек имеет ограничения по размеру в зависимости от ОС и обычно меньше, чем куча Для кучи нет ограничений по размеру
Хранилище Хранит только примитивные переменные и ссылки на объекты, созданные в Heap Space Здесь хранятся все вновь созданные объекты
Доступ к ней осуществляется с использованием системы распределения памяти по принципу «последним поступил – первым обслужен» (LIFO) Доступ к этой памяти осуществляется с помощью сложных методов управления памятью, включающих молодое поколение, старое или постоянное поколение и постоянное поколение.
Жизнь Память стека существует только до тех пор, пока работает текущий метод Пространство кучи существует, пока работает приложение
Эффективность Гораздо быстрее выделять по сравнению с кучей Медленнее выделять по сравнению со стеком
Выделение/освобождение Эта память автоматически выделяется и освобождается при вызове и возврате метода соответственно Пространство кучи выделяется при создании новых объектов и освобождается Gargabe Collector, когда на них больше нет ссылок

6. Заключение

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

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

Часто задаваемые вопросы о памяти Java: как контролировать объем памяти, который использует моя программа Java (т. е. использование ОЗУ Java)?

Короткий ответ

Короткий ответ заключается в том, что вы используете эти параметры командной строки Java, чтобы помочь контролировать использование оперативной памяти приложением:

  • Используйте -Xmx, чтобы указать максимальный размер кучи
  • Используйте -Xms, чтобы указать начальный размер кучи Java
  • Используйте -Xss, чтобы задать размер стека потоков Java

Используйте этот синтаксис, чтобы указать объем памяти, который должна использовать JVM:

Полная команда Java выглядит следующим образом:

Дополнительные сведения см. в остальной части этой статьи. Также см. мои определения кучи и стека Java, если вам не нравятся эти термины.

Более длинный ответ

В качестве предыстории я запускаю приложение Java на устройстве Raspberry Pi с ограниченным объемом памяти. К сожалению, каждый раз, когда я пытаюсь запустить программу, я получаю это сообщение об ошибке размера кучи Java:

«Произошла ошибка при инициализации виртуальной машины. Не удалось зарезервировать достаточно места для кучи объектов. Не удалось создать виртуальную машину Java».

Я знал, что моей программе не нужно много памяти — она просто обращалась к базе данных и генерировала несколько файлов и отчетов — поэтому я решил эту проблему с ограничением памяти, указав максимальный размер кучи Java, который моя программа могла выделить. . В моем случае я не стал слишком много думать об этом и просто выбрал ограничение размера кучи в 64 МБ ОЗУ, и после того, как я установил это ограничение ОЗУ, моя программа заработала нормально.

Установка максимального размера кучи Java (Xmx)

Вы устанавливаете максимальный размер кучи Java для своей программы, используя параметр -Xmx для интерпретатора Java. Чтобы конкретно ограничить размер кучи до 64 МБ, параметр следует указать следующим образом:

При использовании этого параметра ограничения памяти команда Java, которую я использую в своем сценарии оболочки для запуска своей программы Java, выглядит следующим образом:

где THE_CLASSPATH и PROGRAM_NAME — переменные, установленные ранее в моем сценарии. (Важной частью здесь является часть команды -Xmx64m.)

Дополнительные аргументы командной строки Java, связанные с памятью

Дополнительные параметры управления использованием памяти Java-приложениями можно найти в выводе команды java -X. Вот как выглядит вывод этих команд из моей JVM:

Описания размера кучи Java (xms, xmx, xmn)

Покопавшись, я нашел дополнительную информацию о Java xms , xmx и xmn на веб-сайте Apple:

Аргументы памяти Java (xms, xmx, xmn) форматирование (МБ, ГБ)

При установке размера кучи Java вы должны указать аргумент памяти, используя одну из букв «m» или «M» для МБ или «g» или «G» для ГБ.Ваша настройка не будет работать, если вы укажете «МБ» или «ГБ». Допустимые аргументы выглядят следующим образом:

  • -Xms64m или -Xms64M
  • -Xmx1g или -Xmx1G
  • Можно также использовать 2048 МБ для указания 2 ГБ.

Кроме того, убедитесь, что вы используете только целые числа при указании аргументов. Использование -Xmx512m допустимо, но -Xmx0.5g вызовет ошибку.

Читайте также: