Когда программа создает объекты эталонного типа, такие как объекты, массивы и т. Д., Система выделяет кусок памяти для объекта в памяти кучи, а объект хранится в этом фрагменте памяти. Когда на этот кусок памяти больше не ссылается какая -либо эталонная переменная, кусок памяти становится мусором, ожидая переработки механизма сбора мусора. Механизм сбора мусора имеет три характеристики:
Механизм сбора мусора отвечает только за утилизацию объектов в памяти кучи и не будет перерабатывать какие -либо физические ресурсы (такие как подключения к базе данных, открытые файловые ресурсы и т. Д.), И при этом он не будет переработать память, выделяемую на объект, в то же время, кроме способа создания объекта, (например, память, применяемая к объекту, вызывающему Malloc в локальном методе)) в локальном методе)) в локальном методе) в локальном методе) в локальном методе) в локальном методе) в локальном методе) в локальном методе) в локальном методе) в локальном методе) в локальном методе) в локальном методе) в локальном методе) в локальном методе) в локальном методе) в локальном методе).
Программа не может точно контролировать работу сбора мусора, поэтому ее можно рекомендовать только для сбора мусора. Существует два рекомендуемых метода: System.gc () и Runtime.getRuntime (). Gc ()
Перед сборкой мусора его метод infintize () всегда будет называться первым, но он такой же, как время сбора мусора, а метод infintize () также не уверен.
Что касается приведенных выше трех характеристик, есть три проблемы:
1. Работа для очистки должна быть выполнена вручную, чтобы освободить память и другие физические ресурсы, выделенные таким образом, кроме способа создания объектов. И будьте осторожны, чтобы устранить истекшие ссылки на объекты, в противном случае могут быть вызваны OOM.
Ручная очистка обычно использует структуру кода, такую как попытка ... Наконец -то ...
Примеры следующие:
Импорт java.io.fileinputstream; import java.io.filenotFoundException; импорт java.io.ioexception; открытый класс ManualClear {public static void main (string [] args) {fileInputStream fileInputStream = null; try {fileInputStream = new FileInputStream ("./ src/manualClear.java"); } catch (filenotFoundException e) {System.out.println (e.getMessage ()); e.printstacktrace (); возвращаться; } try {byte [] bbuf = new Byte [1024]; int hasread = 0; try {while (((hasread = fileInputStream.read (bbuf))> 0) {system.out.println (new String (bbuf, 0, hasread)); }} catch (ioException e) {e.printstacktrace (); }} наконец {try {fileInputStream.close (); } catch (ioException e) {e.printstackTrace (); }}}}Обычно существует три общих случая OOM, вызванные ссылкой на истекшие объекты. Эти три случая, как правило, нелегко обнаружить, и за короткий промежуток времени не будет проблем. Однако через долгое время количество просочившихся объектов в конечном итоге приведет к сбою программы.
Когда класс управляет памятью сам по себе, вы должны опасаться утечек памяти следующим образом:
Import java.util.arrays; импортировать java.util.emptystackexception; класс стек {private object [] elements; частный размер Int; Private Static Final int default_inital_capacity = 16; public Stack () {elements = new Object [default_inital_capacity]; } public void push (объект e) {ensureCapacity (); Элементы [размер ++] = E; } public Object pop () {if (size == 0) {бросить новый emptyStackexception (); } return Elements [-size]; } private void EnsureCapacity () {if (elements.length == size) {elements = arrays.copyof (elements, 2 * size + 1); }}} открытый класс StackDemo {public static void main (string [] args) {Stack Stack = new Stack (); for (int i = 0; i <10000; i ++) {Stack.push (new object ()); } for (int i = 0; i <10000; i ++) {Stack.pop (); }}}Причина утечек памяти заключается в том, что даже если другие объекты в стеке больше не упоминаются, на элементы [] массив в классе стека все еще содержит ссылки на эти объекты, в результате чего объекты не переработаны сбором мусора. Поэтому, когда класс должен самостоятельно управлять памятью, остерегайтесь того, являются ли эти истекшие ссылки, поддерживаемые внутренне, являются чрезмерными. В этом примере, только после того, как стек будет выпущен, отобразится отображение.
Элементы [размер] = null;
Кэш должен опасаться утечек памяти. Такая ситуация обычно имеет место, когда, как только объект будет помещен в кеш, вполне вероятно, что легко забыть, если он не используется в течение долгого времени. Обычно WakeHashmap можно использовать для представления кэша. После истечения срока действия элементов в кэше их можно автоматически удалить. Или это может периодически выполняться фоновым потоком для очистки истекших элементов в буфере.
Регистрация слушателей или обратных вызовов лучше всего отображается для Unregister.
2. Не звоните в infintize () вручную, он призван к коллекционеру мусора
3. Избегайте использования метода Pinlineize (), если он не используется в качестве оценки конечного условия, чтобы обнаружить, что объект не был должным образом очищен; Он используется в качестве сети безопасности для очистки системных ресурсов при очистке вручную забытых вызовов. Задержка очистки не должна быть очищена. Если вы записываете информацию о забытых чистящих ресурсах одновременно, это также удобно для того, чтобы ошибки были обнаружены позже и изменять код забытого чистки во времени; Освободите не очень критические системные ресурсы, полученные локальным методом в объекте.
Поскольку метод infintize () не является точно гарантированным, лучше не выпускать ключевые ресурсы, но может использоваться в трех случаях, упомянутых выше. Первый случай заключается в следующем:
Класс Книга {Boolean Checkout = false; Общественная книга (логическая проверка) {this.checkout = checkout; } public void checkin () {checkout = false; } @Override Protected void infintize () бросает throwable {if (cakeout) {system.out.println ("error: chearch"); }}} public Class finalizeChobjectuse {public static void main (string [] args) {new Book (true); System.gc (); }}Результаты исполнения:
Ошибка: Проверьте
Объект книги в примере должен находиться в состоянии чека до выпуска, в противном случае его нельзя выпустить. Реализация в завершении может помочь в поиске нелегальных объектов во времени или более напрямую, использовать эталонную переменную, чтобы напрямую ссылаться на нее в завершении, чтобы она могла повторно войти в состояние достижимого, а затем обработать ее снова.
Еще один момент, который следует отметить, заключается в том, что если подкласс переопределяет метод завершения родительского класса, но забывает вручную вызовать супер.
следующее:
класс родитель {@Override Protected void infintize () бросает throwable {System.out.println (getClass (). getName () + "infintize start"); }} класс Son Extens Parent {@Override Protected void infintize () Throws {System.out.println (getClass (). getName () + "infintize start"); }} открытый класс Superfinalizelost {public static void main (string [] args) {new Son (); System.gc (); }}Результаты работы:
Сын завершил старт
или
класс родитель {@Override Protected void infintize () бросает throwable {System.out.println (getClass (). getName () + "infintize start"); }} класс Son Extens Parent {@Override Protected void infintize () Throws {System.out.println (getClass (). getName () + "infintize start"); int i = 5/0; super.finalize (); }} открытый класс Superfinalizelost {public static void main (string [] args) {new Son (); System.gc (); }}Результаты исполнения:
Сын завершил старт
Для второго случая вы можете использовать Try ... наконец ... структура для ее решения, но для первого случая лучше использовать метод, называемый The End Method Guardian. Пример заключается в следующем
класс parent2 {private final Object infintizeguardian = new Object () {Protected void inpintize () бросает throwable {system.out.println («Выполнить логику в методе завершения родительского класса здесь»); }; };} класс son2 extends parent2 {@Override Protected void inpintize () бросает throwable {System.out.println (getClass (). getName () + "infintize start"); int i = 5/0; super.finalize (); }} public class finalizeguardian {public static void main (string [] args) {new son2 (); System.gc (); }}Результаты исполнения:
Выполните логику в методе завершения родительского класса здесь
Son2 завершить начало
Это гарантирует, что операции, требуемые в конечном методе родительского класса, выполняются.
Выше приведено в этой статье, я надеюсь, что это будет полезно для каждого обучения.