Когда сборка мусора Java освобождает выделение памяти?
Я создал объект в Java, Named FOO. FOO содержит большой объем данных. Я не знаю, скажем, для десяти мегабайтного текстового файла, который я втянул в плунжер для манипуляции. (Это просто пример)
Это явно огромный объем пространства, и я хочу освободить его из памяти. Я установил FOO в NULL.
Будет ли это автоматически освобождать это пространство в памяти?
или
Будет ли память, загруженная загруженным текстовым файлом, до автоматического сбора мусора?
Ответы
Ответ 1
Когда вы устанавливаете ссылку на любой объект на null
, он становится доступен для сбора мусора. Он по-прежнему занимает память до фактического запуска сборщика мусора. Нет никаких гарантий относительно того, когда GC будет работать, за исключением того, что он определенно запустится и освободит память от недоступных объектов до того, как будет сброшен OutOfMemoryException
.
Вы можете вызвать System.gc(), чтобы запросить сбор мусора, однако, что это - запрос. Это должно выполняться по усмотрению GC.
Использование WeakReference может помочь в некоторых случаях. См. эту статью Брайана Гетца.
Ответ 2
На самом деле объект не называется FOO. FOO - это имя переменной, которая не является объектом; переменная содержит ссылку на объект. Может быть несколько различных переменных, содержащих ссылки на один и тот же объект.
Сборщик мусора работает, автоматически обнаруживая недостижимые объекты: это объекты, которые приложение больше не может использовать, потому что они безвозвратно забывают, где они находятся (приложение может иметь доступ к любому объекту, для которого он имеет ссылку, включая сохраненные ссылки в поле в объектах, к которым он может получить доступ, и т.д.).
Когда вы устанавливаете FOO = null
, считая, что FOO
содержит в этой точке последнюю доступную ссылку на объект, тогда память немедленно освобождается в следующем смысле: в самом такте, в котором null
установленный в FOO
, объект становится недоступным. Поэтому сборщик мусора заметит этот недостижимый объект и восстановит соответствующий блок памяти; то есть GC будет делать это в следующий раз, когда его можно будет запутать. Конечно, фактические биты, составляющие объект, могут задерживаться в памяти; но этот блок тем не менее "свободен", поскольку распределитель памяти автоматически запускает GC, когда свободная память жесткая. С точки зрения приложения, объект так же хорош, как и мертвый, и соответствующая память свободна, так как эта память будет повторно использована в следующий раз, когда приложение понадобится. Все это автоматически.
В отношении операционной системы ситуация немного сложнее. Если недостижимый объект является свободной памятью с точки зрения приложения, он по-прежнему по-прежнему относится к блоку ОЗУ, посвященному запущенному процессу. Этот блок ОЗУ может быть возвращен в ОС только тогда, когда фактически выполняется GC (который на уровне ОС, часть процесса), отмечает, что объект недоступен, и снисходит, чтобы вернуть блок обратно в ОС, Когда GC работает сильно зависит от технологии GC и того, как приложение распределяет объекты; Кроме того, некоторые GC никогда не вернут блок OS вообще (GC знает, что блок он свободен, распределитель памяти будет повторно использовать его по желанию, но не другие процессы).
System.gc()
- это подсказка для виртуальной машины, так что теперь она запускает GC. Формально это всего лишь подсказка, и виртуальная машина вольна игнорировать ее. На практике он запускает GC, если только VM не будет подчиняться таким командам (с Sun JVM, это вопрос определенного флага командной строки). Даже если GC работает, он не обязательно возвращает память операционной системе. System.gc()
не очень полезно.
Ответ 3
Настройка foo = null;
не означает, что foo
будет немедленно собираться мусором. Вместо этого он будет собран, когда GC будет работать, если это возможно. Когда foo
собирается, любые объекты, для которых он содержит единственную ссылку, также будут иметь право на сбор и поэтому собраны.
Ответ 4
Обратите внимание, что даже вызов System.gc() не гарантирует, что JVM сделает это сразу.
System.gc() - это просто запрос, и нет гарантии, что он будет действовать немедленно.
Ответ 5
Там нет гарантии, что JVM сделает это сразу, вы можете попытаться заставить его с помощью System.gc()
Ответ 6
Сборщик мусора освободит память после того, как вы "уничтожите" ссылку. i.3 Установка ссылки на объект на null. Вы можете использовать опцию принудительного сбора мусора, но вы должны использовать ее с осторожностью. Сборщик мусора предназначен для использования оптимизированного графика, поэтому вызов System.gc() может испортить ритм и, возможно, иметь меньшую производительность из-за ненужного переключения задач.
В качестве альтернативы вы можете думать о способе, который позволяет не загружать большие объемы данных в память. Если вы можете получить это, улучшив код, который будет намного лучше.
Ответ 7
Когда объект становится пригодным для сбора мусора?
- Любые экземпляры, которые не могут быть достигнуты в реальном потоке.
- Циклически ссылающиеся экземпляры, которые не могут быть достигнуты никакими другими экземплярами.
В Java существуют разные типы ссылок. Экземпляры, приемлемые для сбора мусора, зависят от типа ссылки, которую она имеет.
![введите описание изображения здесь]()
В процессе компиляции в качестве метода оптимизации компилятор Java может выбрать присвоение нулевому значению экземпляру, так что он отмечает, что этот экземпляр может быть удален.
class Animal
{
public static void main(String[] args) {
Animal lion = new Animal();
System.out.println("Main is completed.");
}
protected void finalize() {
System.out.println("Rest in Peace!");
}
}
В вышеприведенном классе экземпляр lion никогда не используется за пределами строки создания. Таким образом, компилятор Java в качестве меры оптимизации может назначить lion = null сразу после строки создания. Таким образом, даже до выхода SOP финализатор может печатать "Rest in Peace!". Мы не можем доказать это детерминистически, поскольку это зависит от реализации JVM и памяти, используемой во время выполнения. Но есть одно обучение, компилятор может выбрать бесплатные экземпляры ранее в программе, если видит, что в будущем он больше не ссылается.
http://javapapers.com/java/how-java-garbage-collection-works/