Предисловие
Я видел вопрос на Segmentfault: у Java есть полный механизм GC, так что в Java возникает проблема с утечкой памяти, и могу ли я дать случай утечки памяти. Этот вопрос дает полный ответ на этот вопрос.
Введение в механизм утилизации мусора
Во время запуска программы каждый объект создается определенное количество памяти для хранения данных объектов. Если вы просто продолжаете распределять память, то программа будет столкнуться с проблемой недостаточной памяти рано или поздно. Таким образом, на любом языке будет механизм восстановления памяти, чтобы освободить память о истекших объектах, чтобы убедиться, что память может быть использована повторно.
Механизм утилизации памяти может быть разделен на два типа в соответствии с ролями реализации. Одним из них является то, что программисты вручную реализуют выпуск памяти (например, C-языка), а другой-встроенный механизм рециркуляции памяти языка, такой как механизм сбора мусора Java, который должен быть представлен в этой статье.
Механизм сбора мусора Java
В среде выполнения программы виртуальная машина Java предоставляет системную сбору мусора (GC, коллекция Carbest), которая отвечает за восстановление памяти, занятой объектами, которые потеряли ссылки. Предварительным условием для понимания GC является понимание некоторых концепций, связанных с сборкой мусора. Эти концепции представлены один за другим в следующем.
Состояние объекта в области кучи JVM
Экземпляры Java -объектов хранятся в области кучи JVM. Для потоков GC эти объекты имеют три состояния.
1. Touchable State: в программе существуют переменные ссылки, поэтому этот объект является трогательным состоянием.
2. Реактивированное состояние: когда в программе нет переменных в программе, объект будет изменен от осязаемого состояния в реактивированное состояние. Поток CG будет подготовлен к вызову метода завершения этого объекта в определенное время (метод завершения унаследовает или переписывает дочерний объект). Код в методе завершения может преобразовать объект в осязаемое состояние, в противном случае объект будет преобразован в неприкасаемое состояние.
3. Неприкасаемое состояние: поток GC может перерабатывать память этого объекта только тогда, когда объект находится в неприкасаемом состоянии.
Чтобы правильно освободить объекты, GC должен отслеживать статус выполнения каждого объекта, включая приложение, цитирование, цитирование, назначение и т. Д. GC должен контролировать его, поэтому GC будет знать, независимо от того, находится ли объект в любом состоянии выше.
Как упомянуто выше, потоки GC выполнят метод завершения воскресных объектов состояния в определенное время. Так когда это будет выполнено? Поскольку различные реализаторы JVM могут использовать разные алгоритмы для управления GC, в любое время разработчики не могут предсказать время потоков GC, выполняющих различные операции (включая обнаружение состояния объекта, освобождение памяти объекта и вызов объекта завершить методы). Хотя поток GC можно напомнить о выполнении операций сбора мусора как можно скорее через функции System.gc () и Runtime.gc (), это не может гарантировать, что поток GC будет немедленно выполнять соответствующие операции по переработке.
Утечка памяти
Утечки памяти вызваны неправильными конструкциями, что программа не может выпустить память, которая больше не используется, что приводит к отходу ресурсов. GC автоматически очистит память, занятую объектами, которые потеряли ссылки. Однако, если на некоторые объекты всегда упоминаются из -за ошибок программирования, возникнет утечка памяти.
Например, следующий пример. Массив используется для реализации стека, с двумя операциями: вход в стек и выход стека.
Импорт com.sun.javafx.collections.elementObservableListDecorator; импорт com.sun.swing.internal.plaf.metal.resources.metal_sv; import java.beans.exceptionlistener; import java.util.emptystackexception;/*** Создан Peng на 14-9-21. */public class mystack {private object [] elements; Private Int Increment = 10; private int size = 0; public mystack (int size) {elements = new Object [size]; } // Поместите стек public void push (Object o) {apity (); элементы [size ++] = o; } // Поместите стек Public Object Pop () {if (size == 0). Выбросить новый emptyStackexception (); возвращаемые элементы [-размер]; } // Увеличение емкости стека Private void емкость () {if (elements.length! = Size) return; Object [] newarray = новый объект [elements.length + увеличение]; System.ArrayCopy (элементы, 0, Newarray, 0, Size); } public static void main (string [] args) {mystack stach = new mystack (100); для (int i = 0; i <100; i ++) stack.push (новое целое число (i)); for (int i = 0; i <100; i ++) {System.out.println (stack.pop (). toString ()); }}}Эта программа доступна и поддерживает общие операции ввода стека и ввода стека. Тем не менее, существует проблема, с которой не обработалась хорошо, то есть, когда операция стека отпускается, ссылка на элемент стека в массиве не выпускается, что заставляет программу сохранять ссылку на этот объект (этот объект ссылается на массив). GC всегда считает, что этот объект доступен, что означает, что нет необходимости говорить о том, чтобы выпустить его память. Это типичный случай утечек памяти. Для этого измененный код:
// стекает public Object Pop () {if (size == 0) выбрать новый emptyStackexception (); Объект o = элементы [-размер]; Элементы [размер] = null; вернуть O; }Приведенная выше статья имеет глубокое понимание механизма сбора мусора Java и утечек памяти. Это весь контент, которым я поделился с вами. Я надеюсь, что это может дать вам ссылку, и я надеюсь, что вы сможете поддержать Wulin.com больше.