← Назад к вопросам
Что происходит с приложением когда Garbage Collector нужно удалить память
1.0 Junior🔥 141 комментариев
#JVM и управление памятью#Основы Java
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Что происходит с приложением во время Garbage Collection
Краткий ответ
Когда Garbage Collector (GC) работает, приложение временно останавливается (выполняется Stop The World пауза). В это время:
- Все потоки приложения приостанавливаются
- JVM анализирует и удаляет недостижимые объекты
- После завершения GC потоки возобновляют работу
- Пользователь заметит задержку в ответе приложения
Этапы Garbage Collection
1. Mark (Пометка)
JVM сканирует всё приложение и помечает живые объекты:
┌─────────────────────────────────────┐
│ Heap Memory │
│ ┌────┐ ┌────┐ ┌────┐ ┌────┐ │
│ │ A │→ │ B │→ │ C │ │ D │ │
│ └────┘ └────┘ └────┘ └────┘ │
│ ✓ живой ✓ живой ✓ живой ✗ мёртвый
└─────────────────────────────────────┘
public class GCDemo {
public static void main(String[] args) {
// На момент GC:
Object obj1 = new Object(); // Помечается как живой (есть ссылка)
Object obj2 = new Object();
Object obj3 = new Object(); // Помечается как мёртвый (нет ссылки)
obj3 = null; // Разорвали связь
System.gc(); // Вызов GC
// obj3 будет удалён
}
}
2. Sweep (Удаление)
GC удаляет помеченные мёртвые объекты и освобождает память.
3. Compact (Уплотнение) - опционально
Nекоторые GC-алгоритмы уплотняют памяти, перемещая живые объекты вместе.
Stop The World Пауза
Время ─────────────────────────────────────────────────→
│ Приложение │ GC Pause │ Приложение │ GC Pause │ Приложение │
│ работает │ СТОП │ работает │ СТОП │ работает │
└────────────┴──────────┴───────────┴──────────┴───────────┘
1сек 0.5сек 2сек 0.3сек ...
Влияние на приложение
1. GUI приложения (Desktop)
// UI замораживается во время GC
public class UIApp extends JFrame {
public UIApp() {
setSize(400, 300);
setVisible(true);
}
// Во время GC паузы все действия игнорируются
// Клик кнопки может не обработаться
// Экран может "затормозить"
}
2. Web приложения (Spring Boot)
@RestController
public class UserController {
@GetMapping("/api/users/{id}")
public ResponseEntity<User> getUser(@PathVariable Long id) {
// Если GC произойдёт во время обработки запроса,
// ответ задержится на время паузы GC
// Клиент получит задержку в ответе
User user = userService.findById(id);
return ResponseEntity.ok(user);
}
}
// Если GC пауза = 500ms, то ответ задержится на 500ms
// Для real-time приложений это может быть критично
3. Real-time системы
// Торговля на бирже, высокочастотный трейдинг
public class HighFrequencyTrade {
public void executeTrade() {
// GC пауза в 100ms может означать потерю миллионов!
long startTime = System.nanoTime();
// Если GC сработает здесь...
// даже 10ms паузы = потеря возможности
long endTime = System.nanoTime();
System.out.println("Trade executed in " + (endTime - startTime) + " ns");
}
}
Типы GC и их влияние на приложение
1. Minor GC (сборка молодого поколения)
Пауза: 1-10ms (обычно короткая)
Частота: каждые несколько секунд
Влияние: минимальное
// Быстро создаём много временных объектов
public void minorGCExample() {
for (int i = 0; i < 1_000_000; i++) {
String temp = "Object " + i; // Создание в Young Generation
// Minor GC сработает несколько раз
// Это быстро, паузы ~5ms
}
}
2. Major GC / Full GC (сборка всей памяти)
Пауза: 100-5000ms (очень долгая!)
Частота: редко
Влияние: критическое для некоторых приложений
// Множество долгоживущих объектов
public class FullGCExample {
private List<byte[]> cache = new ArrayList<>();
public void fillMemory() {
for (int i = 0; i < 10_000; i++) {
cache.add(new byte[100_000]); // 1GB памяти
}
// Full GC может произойти и длиться несколько секунд!
}
}
Мониторинг GC паузы
public class GCMonitor {
public static void main(String[] args) {
// Запуск с параметром: -XX:+PrintGCDetails -XX:+PrintGCTimeStamps
// Логи GC покажут:
// [GC pause (G1 Humongous Allocation) 1234.567: 1.234 secs]
// ↑ что произошло ↑ длительность паузы
}
// Или программно
public void monitorGC() {
MemoryMXBean memoryMXBean = ManagementFactory.getMemoryMXBean();
List<GarbageCollectorMXBean> gcBeans =
ManagementFactory.getGarbageCollectorMXBeans();
for (GarbageCollectorMXBean gcBean : gcBeans) {
System.out.println(gcBean.getName() + ": " +
gcBean.getCollectionCount() + " сборок");
System.out.println("Total time: " +
gcBean.getCollectionTime() + " ms");
}
}
}
Параметры JVM для управления GC
# Выбор GC алгоритма
-XX:+UseG1GC # G1GC (рекомендуется для новых приложений)
-XX:+UseZGC # ZGC (очень низкие паузы, Java 15+)
-XX:+UseConcMarkSweepGC # CMS (устаревший)
# Размер памяти
-Xms2G -Xmx4G # Min/Max heap size
# Максимальная пауза
-XX:MaxGCPauseMillis=200 # Целевая пауза 200ms (G1GC попытается)
# Логирование GC
-Xlog:gc*:file=gc.log:time,uptime,level,tags
Практические рекомендации
- Для low-latency приложений используйте ZGC или Shenandoah GC (паузы < 10ms)
- Избегайте создания ненужных объектов — меньше работы для GC
- Мониторьте GC логи в production
- Устанавливайте правильный размер heap (не слишком большой, не слишком маленький)
- Помните о cost of GC при выборе архитектуры и алгоритмов
- Профилируйте приложение для выявления "memory leaks" (объекты, которые не удаляются)