Может ли быть утечка памяти в Java?
Ответ в том, что это зависит от того, о какой утечке памяти вы говорите.
Классические утечки памяти в C / C ++ происходят, когда приложение игнорирует free
или dispose
объект, когда оно завершает работу с ним, и оно протекает. Циклические ссылки являются частным случаем этого, когда приложение с трудом знает, когда нужно free
/ dispose
, и в результате этого пренебрегает. Схожие проблемы связаны с тем, что приложение использует объект после его освобождения или пытается дважды его освободить. (Вы можете назвать последние проблемы утечками памяти или просто ошибками. В любом случае ...)
Java и другие (полностью 1 ) управляемые языки в основном не страдают от этих проблем, потому что GC заботится об освобождении объектов, которые более недоступны. (Конечно, проблем с висящим указателем и двойным отсутствием не существует, и циклы не являются проблематичными, как для «умных указателей» C / C ++ и других схем подсчета ссылок.)
Но в некоторых случаях GC в Java будет пропускать объекты, которые (с точки зрения программиста) следует собирать мусором. Это происходит, когда GC не может понять, что объект не может быть достигнут:
- Логика / состояние программы может быть таким, что пути выполнения, которые будут использовать некоторую переменную, не могут возникнуть. Разработчик может видеть это как очевидное, но GC не может быть уверен, и ошибается на стороне осторожности (как это требуется).
- Программист может ошибаться, и сборщик мусора избегает того, что в противном случае может привести к зависанию.
(Обратите внимание, что причины утечек памяти в Java могут быть простыми или довольно неуловимыми; см. Ответ @ jonathan.cone для некоторых неуловимых. Последний может включать внешние ресурсы, которые не должны в любом случае положитесь на GC.)
В любом случае, вы можете столкнуться с ситуацией, когда нежелательные объекты не могут быть собраны мусором, и зависают, связывая память ... утечка памяти.
Тогда возникает проблема, заключающаяся в том, что приложение или библиотека Java могут выделять объекты вне кучи через собственный код, которым необходимо управлять вручную. Если приложение / библиотека содержит ошибки или используется неправильно, вы можете получить утечку памяти. (Например: утечка памяти Android Bitmap ... с учетом того, что эта проблема исправлена в более поздних версиях Android.)
1 - Я имею в виду пару вещей. Некоторые управляемые языки позволяют писать неуправляемый код, в котором можно создавать классические утечки памяти. Некоторые другие управляемые языки (или, точнее, языковые реализации) используют подсчет ссылок, а не надлежащий сборщик мусора. Диспетчеру хранилища на основе подсчета ссылок необходимо что-то (например, приложение) для прерывания циклов ... иначе произойдет утечка памяти.