Перейти к основному содержимому

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

· 4 мин. чтения

1. Обзор

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

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

2. Доступ к параметрам памяти

Каждое приложение Java имеет единственный экземпляр java.lang.Runtime , который может помочь нам понять текущее состояние памяти приложения. Статический метод Runtime#getRuntime можно вызвать для получения одноэлементного экземпляра среды выполнения .

2.1. Общая память

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

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

2.2. Свободная память

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

2.3. Максимальная память

Метод Runtime#maxMemory возвращает максимальный объем памяти, который JVM попытается использовать. Как только использование памяти JVM достигает этого значения, она не будет выделять больше памяти, а вместо этого будет чаще собирать мусор.

Если объектам JVM по-прежнему требуется больше памяти даже после запуска сборщика мусора, JVM может сгенерировать исключение времени выполнения java.lang.OutOfMemoryErro r.

3. Пример

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

ArrayList<Integer> arrayList = new ArrayList<>();
System.out.println("i \t Free Memory \t Total Memory \t Max Memory");
for (int i = 0; i < 1000000; i++) {
arrayList.add(i);
System.out.println(i + " \t " + Runtime.getRuntime().freeMemory() +
" \t \t " + Runtime.getRuntime().totalMemory() +
" \t \t " + Runtime.getRuntime().maxMemory());
}

// ...
Output:
i Free Memory Total Memory Max Memory
0 254741016 257425408 3817865216
1 254741016 257425408 3817865216
...
1498 254741016 257425408 3817865216
1499 253398840 257425408 3817865216
1500 253398840 257425408 3817865216
...
900079 179608120 260046848 3817865216
900080 302140152 324534272 3817865216
900081 302140152 324534272 3817865216
...
  • Строка 1498: значение Runtime#freeMemory уменьшается, когда в куче Java выделяется достаточно места для объектов.
  • Строка 900080: на данный момент JVM имеет больше свободного места, так как сборка мусора запущена, поэтому значения Runtime#freeMemory и Runtime#totalMemory увеличиваются.

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

4. Настройка параметров памяти

Мы можем переопределить значения по умолчанию для параметров памяти JVM , установив пользовательские значения для определенных флагов при запуске нашей Java-программы, чтобы достичь требуемой производительности памяти:

  • -Xms: значение, присвоенное флагу -Xms , устанавливает начальное и минимальное значение кучи Java. Его можно использовать в тех случаях, когда нашему приложению требуется больше памяти, чем минимум по умолчанию при запуске JVM.
  • -Xmx: Точно так же мы можем установить максимальное значение для пространства кучи, назначив его флагу -Xmx . Его можно использовать, когда мы хотим ограничить объем памяти, который будет использовать наше приложение, намеренно.

Также обратите внимание, что значение -Xms должно быть меньше или равно значению -Xmx .

4.1. Применение

java -Xms32M -Xmx64M Main                                                                                        
Free Memory : 31792664 bytes
Total Memory : 32505856 bytes
Max Memory : 59768832 bytes

java -Xms64M -Xmx64M Main
Free Memory : 63480640 bytes
Total Memory : 64487424 bytes
Max Memory : 64487424 bytes

java -Xms64M -Xmx32M Main
Error occurred during initialization of VM
Initial heap size set to a larger value than the maximum heap size

5. Вывод

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

Мы также показали, как назначать пользовательские значения для определенных флагов, что приводит к разному поведению памяти JVM для разных сценариев.