← Назад к вопросам
Что произойдет с объектом, если им никто не пользуется?
1.7 Middle🔥 201 комментариев
#JVM и управление памятью
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
# Что произойдет с объектом, если им никто не пользуется?
Ответ: объект будет удален Garbage Collector (сборщик мусора) и его память освобождена для использования другими объектами.
Жизненный цикл объекта в Java
1. Создание → new Object()
2. Использование → ссылка на объект существует
3. Недостижимость → нет ссылок на объект
4. Garbage Collection → JVM удаляет объект
5. Освобождение памяти → память возвращена в heap
Понятие "никто не пользуется"
// Есть ссылка - объект в памяти
User user = new User("John");
System.out.println(user.getName()); // используется
// Удаляем ссылку - объект больше не используется
user = null;
// или выход из scope
{
User localUser = new User("Jane");
// используется
} // localUser выходит из scope → ссылка теряется
// Объект становится недостижимым (unreachable)
// GC заметит это и удалит объект
Как JVM определяет недостижимость?
Mark and Sweep алгоритм
1. Mark фаза: JVM ищет все ссылки на объекты
- Начинает с корневых ссылок (локальные переменные, static поля)
- Помечает достижимые объекты
2. Sweep фаза: JVM удаляет непомеченные объекты
- Освобождает память
- Уплотняет heap
Пример garbage collection
public class GarbageCollectionExample {
public static void main(String[] args) {
// Объект 1: создан
User user1 = new User("Alice");
// Объект 2: создан
User user2 = new User("Bob");
// Переприсваиваем ссылку
user1 = user2; // объект Alice больше не достижим!
// GC удалит объект Alice
// Обнуляем ссылку
user2 = null; // объект Bob становится недостижимым
// GC удалит объект Bob
}
// Конец метода - локальные переменные удаляются
}
Когда запускается GC?
- Автоматически когда heap переполнен
- System.gc() явный вызов (не гарантирован)
- Зависит от JVM (G1GC, ZGC, CMS и т.д.)
Проблемы с забытыми ссылками
Memory Leak: забыли удалить ссылку
public class Cache {
private List<User> cache = new ArrayList<>();
public void addUser(User user) {
cache.add(user); // добавили в cache
}
// ПРОБЛЕМА: нет метода для удаления из cache
// cache будет расти и никогда не очищаться!
}
Решение: WeakReference
public class SmartCache {
private Map<String, WeakReference<User>> cache = new WeakHashMap<>();
public void addUser(String key, User user) {
cache.put(key, new WeakReference<>(user));
}
// Если на пользователя нет других ссылок,
// он будет удален GC, даже если в cache
}
Типы ссылок в Java
// 1. Strong reference (обычная ссылка)
User user = new User(); // будет удалён только если user = null
// 2. Weak reference
WeakReference<User> weakUser = new WeakReference<>(user);
// Если нет других ссылок, GC удалит объект
// 3. Soft reference
SoftReference<User> softUser = new SoftReference<>(user);
// GC удалит только если мало памяти
// 4. Phantom reference
PhantomReference<User> phantomUser = new PhantomReference<>(user, queue);
// Уведомляет о готовности к удалению
Финализация объектов
finalize() метод (устаревший)
public class Resource {
private Connection conn;
@Override
protected void finalize() throws Throwable {
if (conn != null) {
conn.close(); // очистка при удалении
}
super.finalize();
}
}
Проблемы:
- finalize() может не вызваться никогда
- Замедляет GC
- Сложно предсказать когда вызовется
Правильный способ: try-with-resources
try (Connection conn = getConnection()) {
// использование
} // автоматически закроется
Мониторинг памяти
public class MemoryMonitor {
public static void main(String[] args) {
Runtime runtime = Runtime.getRuntime();
long usedMemory = runtime.totalMemory() - runtime.freeMemory();
System.out.println("Used: " + usedMemory / 1024 / 1024 + " MB");
// Принудительно запустить GC (не рекомендуется)
System.gc();
usedMemory = runtime.totalMemory() - runtime.freeMemory();
System.out.println("After GC: " + usedMemory / 1024 / 1024 + " MB");
}
}
Лучшие практики
- Не полагайся на finalize()
- Используй try-with-resources для ресурсов
- Избегай memory leaks через WeakReference
- Не вызывай System.gc() без необходимости
- Профилируй память если нужно
Резюме
Объект, на который нет ссылок, становится недостижимым. Garbage Collector заметит это и удалит объект, освободив память. В Java управление памятью автоматическое, что избавляет от manual memory management как в C++.