← Назад к вопросам
Как определить, сколько памяти потребляет Java-приложение, упакованное в *.jar, при запуске через команду java-jar, если оно завершается с ошибкой "No heap space"?
2.0 Middle🔥 151 комментариев
#Другое
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
# Диагностика потребления памяти Java приложения при ошибке "No heap space"
Ошибка "java.lang.OutOfMemoryError: Java heap space" означает, что приложение исчерпало отведённую кучу. Нужно определить текущее потребление и настроить параметры запуска.
Способ 1: Установка явных лимитов памяти и мониторинг
Базовое увеличение памяти
# Минимальный вариант
java -jar application.jar
# С явными параметрами памяти
java -Xms512m -Xmx2g -jar application.jar
# -Xms512m = начальный размер heap = 512 МБ
# -Xmx2g = максимальный размер heap = 2 ГБ
# Рекомендуемые значения
java -Xms1g -Xmx4g -jar application.jar
# Для больших приложений
java -Xms4g -Xmx8g -XX:+UseG1GC -jar application.jar
Способ 2: Включение GC логирования для анализа
# Java 8
java -Xms1g -Xmx4g \
-XX:+PrintGCDetails \
-XX:+PrintGCDateStamps \
-Xloggc:gc.log \
-jar application.jar
# Java 9+
java -Xms1g -Xmx4g \
-Xlog:gc*:file=gc.log:time,uptime,level,tags \
-jar application.jar
Анализируем gc.log:
2024-03-22T10:15:30.123+0000: 5.432: [GC (Allocation Failure) [PSYoungGen: 262144K->32768K(262144K)] 262144K->65536K(1048576K), 0.0245031 secs]
↑ ↑
Время GC Общее потребление
Способ 3: Создание и анализ heap dump
Способ 3a: Запуск с автоматическим dump при OOM
java -Xms1g -Xmx4g \
-XX:+HeapDumpOnOutOfMemoryError \
-XX:HeapDumpPath=./heap-dump.hprof \
-jar application.jar
# При ошибке OOM автоматически создается файл heap-dump.hprof
Способ 3b: Ручное создание dump текущего приложения
# 1. Получаем PID приложения
jps -l
# Output: 12345 /path/to/application.jar
# 2. Создаём dump в режиме реального времени
jmap -dump:live,format=b,file=heap-dump.hprof 12345
# 3. Анализируем dump с помощью Eclipse Memory Analyzer
# или jhat (встроенный инструмент)
jhat heap-dump.hprof
# Откроется веб-интерфейс на http://localhost:7000
Способ 4: Мониторинг в реальном времени с JMX
Включаем JMX при запуске
java -Xms1g -Xmx4g \
-Dcom.sun.management.jmxremote \
-Dcom.sun.management.jmxremote.port=9010 \
-Dcom.sun.management.jmxremote.authenticate=false \
-Dcom.sun.management.jmxremote.ssl=false \
-Djava.rmi.server.hostname=localhost \
-jar application.jar
Подключаемся через JConsole или VisualVM
# JConsole (встроенный)
jconsole
# затем выбираем процесс из списка и монитор Memory
# VisualVM (мощнее)
jvisualvm
# File → Add JMX Connection → localhost:9010
Способ 5: Использование команды jstat для статистики
# Получаем PID
jps -l
# Смотрим статистику GC каждую секунду
jstat -gc 12345 1000
# Output:
# S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU
# 2048.0 2048.0 0.0 2048.0 16384.0 12288.0 20480.0 15360.0 24576.0 23552.0 0.0 0.0
#
# S0C/S1C = Young generation survivor space
# EC = Eden space
# OC = Old generation capacity
# OU = Old generation used
# Более подробная статистика
jstat -gcutil 12345 1000
# Output (проценты):
# S0 S1 E O M CCS YGC YGCT FGC FGCT GCT
# 0.00 100.00 50.00 75.00 96.00 0.00 12 1.234 2 0.456 1.690
Способ 6: Анализ размера объектов в коде
// Если нужно понять потребление памяти программно
public class MemoryAnalyzer {
public static void main(String[] args) {
Runtime runtime = Runtime.getRuntime();
// Общая память, выделенная для JVM
long totalMemory = runtime.totalMemory();
// Свободная память
long freeMemory = runtime.freeMemory();
// Использованная память
long usedMemory = totalMemory - freeMemory;
// Максимальная доступная память
long maxMemory = runtime.maxMemory();
System.out.println("=== Memory Stats ===");
System.out.println("Total Memory: " + formatBytes(totalMemory));
System.out.println("Used Memory: " + formatBytes(usedMemory));
System.out.println("Free Memory: " + formatBytes(freeMemory));
System.out.println("Max Memory: " + formatBytes(maxMemory));
System.out.println("Available for use: " + formatBytes(maxMemory - usedMemory));
}
private static String formatBytes(long bytes) {
if (bytes <= 0) return "0 B";
final String[] units = new String[] { "B", "KB", "MB", "GB" };
int digitGroups = (int) (Math.log10(bytes) / Math.log10(1024));
return String.format("%.2f %s", bytes / Math.pow(1024, digitGroups),
units[digitGroups]);
}
}
Способ 7: Встроенные флаги для диагностики
# Показать настройки памяти при запуске
java -XX:+PrintFlagsFinal -jar application.jar | grep HeapSize
# Output:
# long InitialHeapSize = 268435456 (256 MB)
# long MaxHeapSize = 4294967296 (4 GB)
# Печать информации о GC при каждом сборке
java -Xms1g -Xmx4g \
-XX:+UnlockDiagnosticVMOptions \
-XX:+TraceClassLoading \
-jar application.jar
# Рекомендуемые настройки для production
java -Xms2g -Xmx4g \
-XX:+UseG1GC \
-XX:MaxGCPauseMillis=200 \
-XX:+ParallelRefProcEnabled \
-XX:+AlwaysPreTouch \
-Xlog:gc*:file=gc.log:time,uptime,level,tags \
-jar application.jar
Практический пример полной диагностики
#!/bin/bash
# debug-memory.sh
APP_JAR="application.jar"
HEAP_DUMP_FILE="heap-dump-$(date +%s).hprof"
GC_LOG="gc-$(date +%s).log"
echo "Starting application with memory monitoring..."
echo "Heap dump will be saved to: $HEAP_DUMP_FILE"
echo "GC log will be saved to: $GC_LOG"
java \
-Xms512m \
-Xmx2g \
-XX:+UseG1GC \
-XX:+HeapDumpOnOutOfMemoryError \
-XX:HeapDumpPath="$HEAP_DUMP_FILE" \
-Xlog:gc*:file="$GC_LOG":time,uptime,level,tags \
-Dcom.sun.management.jmxremote \
-Dcom.sun.management.jmxremote.port=9010 \
-Dcom.sun.management.jmxremote.authenticate=false \
-Dcom.sun.management.jmxremote.ssl=false \
-Djava.rmi.server.hostname=localhost \
-jar "$APP_JAR"
echo "Application finished. Check $HEAP_DUMP_FILE and $GC_LOG"
Рекомендации для решения проблемы
Шаг 1: Определи реальное потребление
# Запусти с увеличенной памятью и мониторь
java -Xms1g -Xmx4g -Xlog:gc*:file=gc.log -jar app.jar
# Проверь gc.log — найди максимальный размер heap перед OOM
Шаг 2: Если OOM вызывает утечка памяти
# Создай heap dump при ошибке
java -Xmx4g \
-XX:+HeapDumpOnOutOfMemoryError \
-XX:HeapDumpPath=./dump.hprof \
-jar app.jar
# Затем анализируй dump в Eclipse MAT (Memory Analyzer Tool)
# Ищи retained objects с большим размером
Шаг 3: Оптимизируй
- Уменьшай размеры коллекций
- Освобождай неиспользуемые объекты
- Используй более эффективные структуры данных
- Включи G1GC для больших heap:
-XX:+UseG1GC
Таблица параметров для разных сценариев
| Сценарий | Параметры |
|---|---|
| Микросервис | -Xms512m -Xmx1g -XX:+UseG1GC |
| Веб-приложение | -Xms1g -Xmx4g -XX:+UseG1GC -XX:MaxGCPauseMillis=200 |
| Обработка больших данных | -Xms4g -Xmx16g -XX:+UseG1GC -XX:MaxGCPauseMillis=500 |
| Production система | -Xms2g -Xmx8g -XX:+UseG1GC -XX:+ParallelRefProcEnabled -XX:+AlwaysPreTouch |
Диагностику памяти начинай с включения GC логирования и heap dump при OOM. Это даст 80% информации для решения проблемы.