Java - когда этот объект выгружается? - PullRequest
3 голосов
/ 08 октября 2011

Вот мой код:

    LinkedList <Mono> list = new LinkedList ();

    list.add(new Mono (2, 2));
    list.add(new Mono (1, -1));
    list.remove (1);

Теперь, когда второй элемент в списке удаляется, объект уничтожается? IE, он проходит сборку мусора?

Ответы [ 9 ]

4 голосов
/ 08 октября 2011

РЕДАКТИРОВАТЬ для нового вопроса:

Да, объект будет иметь право на сборку мусора, если не осталось сильных ссылок. Однако JVM будет пытаться очистить мусор большими партиями, чтобы он мог быть собран в любое произвольное позднее время (или никогда, если JVM завершит работу до того, как GC доберется до него)

Старый ответ :

Разгрузка класса - редкое событие, которое обычно не происходит своевременно (если оно вообще происходит).

В частности, даже после того, как он получит право на сбор, он не будет собираться вместе с «обычными» новыми объектами, такими как ваши экземпляры Mono - он часто находится в специальном другом пуле (PermGen в Oracle JVM)

Вы должны предположить, что после загрузки класса он останется загруженным навсегда. Как только вы попадаете в веб-приложения в контейнерах, это не всегда верно, но любой, кто работал в этих средах, может в целом сказать вам, насколько хорошо он (не) работает.

2 голосов
/ 08 октября 2011

Сборка мусора в Java, как правило, недетерминирована, поскольку , когда это произойдет, и какие подходящие объекты GC выселит ("освободит"), когда цикл GC действительно произойдет .

Таким образом, единственное надежное правило таково:

  1. Объект останется доступным (не будет GC 'освобожден / освобожден / выселен), пока он существует сильно достижимым .(См. «Жизненный цикл достижимости объектов» в Глава 9 «Внутри виртуальной машины Java» , чтобы узнать, что это значит - в целом очень хорошее чтение, если немного устарело.)

В опубликованном коде remove приведет к тому, что второй объект new Mono(1, -1) будет приемлемым для восстановления, так как на него больше нет сильных ссылок (объект более недоступен).Фактическое выселение (если оно произойдет) произойдет «некоторое время спустя» и может даже не быть следующим циклом сбора мусора.Использование финализаторов (ick) еще более усложняет ситуацию.

Обратите внимание, что для объекта никогда не гарантируется для GC-обработки (например, JVM может просто завершить [ab] нормально), а такжеточная семантика конкретной реализации GC может отличаться и все еще быть соответствующей виртуальной машиной - все сводится к достижимости.

Счастливое кодирование.

0 голосов
/ 12 октября 2011

Вы имеете в виду, имеет ли экземпляр Mono право на сборку мусора или экземпляр списка подходит для сбора мусора?

Экземпляр mono будет иметь право на сборку мусора после его удаления (при условии, чтоКод не создан по ссылкам на него.

Список НЕ подходит для сборки мусора только потому, что он очищен. Пустой список не может быть собран сборщиком мусора, поскольку он является допустимым объектом, который можно читать и записывать снова.

An, как уже отмечали другие. Мы говорим о праве на сборку мусора. Сборщик мусора не обязательно запускается сразу.

0 голосов
/ 08 октября 2011

Простой ответ заключается в том, что для вас не должно иметь значения, когда объект Java собирается мусором.Единственное, что вам нужно знать, это то, что получит сборщик мусора до того, как вашей программе не хватит памяти ... при условии , что объект недоступен.

Сложный ответ включает в себя другие вещи:

  • Сборщик мусора обычно работает в то время, которое вы не можете предсказать.

  • Вы можете позвонить System.gc(), чтобы предложить JVM запустить GC сейчас, но:

    • JVM может игнорировать эту подсказку, и

    • Обычно это плохая идея.(Запуск ГХ стоит дорого, и у вашего приложения недостаточно информации, чтобы знать, когда это лучше всего сделать с точки зрения эффективности.)

  • Любой конкретный прогонGC не гарантирует восстановление всех недоступных объектов.У GC есть много «умов», которые направлены на то, чтобы сделать GC максимально эффективным или сократить время «паузы».Один из «умов» - не каждый раз собирать всю кучу GC.

  • Нет никаких гарантий, что GC вообще будет работать или будет работать до выключения JVM.

  • Из-за вышеизложенного, плохая идея писать приложение так, чтобы оно зависело от конкретного восстанавливаемого объекта /удаляются в определенное время.


(Единственное, что должно беспокоить вас в управлении памятью, это утечки памяти; например, когда ваше приложение хранит ссылки на нежелательныеобъекты, которые препятствуют тому, чтобы эти объекты когда-либо стали недоступными. Но вопрос не в этом.)

0 голосов
/ 08 октября 2011

Я думаю, что люди запутались с используемой вами терминологией.Я полагал, что вы спрашиваете, будет ли ваш Mono объект «удален» / «сборщик мусора».

Давайте посмотрим на remove(1), который вы вызываете ...

Это функция удаления, которую вы вызываете, как определено в java.util.LinkedList:

public E remove(int index) {
    return remove(entry(index));
}

Функция выше вызывает следующее (посмотрите мои комментарии в коде):

private E remove(Entry<E> e) {
if (e == header)
    throw new NoSuchElementException();

    E result = e.element;
    e.previous.next = e.next; //Preceding element refers now to the one after the element to be removed;
    e.next.previous = e.previous; //Next element refers now to the one before the one to be removed;
    e.next = e.previous = null; //Element to be removed doesn't refer to anything anymore;
    e.element = null;
    size--;
    modCount++;
    return result;
}

После того, как функция, которую вы вызываете, завершается, больше нет возможности обратиться к вашему Mono (1, -1).Этот моно объект больше недоступен.Это означает, что он получит право на сбор мусора.Имейте в виду, что «право» может означать, что он никогда не будет собирать мусор ... Подробнее о GC здесь .

0 голосов
/ 08 октября 2011

Много ответов, так вот мое вращение. Подумайте о «объеме», концепции компьютерных языков, которая описывает, где и когда вы можете получить доступ к названному биту памяти.

Вот ваш оригинальный код с добавлением вашего предполагаемого удаления второго члена списка:

LinkedList <Mono> list = new LinkedList ();

list.add(new Mono (2, 2));
list.add(new Mono (1, -1));
list.remove (1);
list.remove (2);`

В точке list.remove (2) на объект «список» все еще можно ссылаться. Конечно, он пуст, но тогда вы можете решить добавить в него новый Mono. Вы можете это сделать, потому что «list» по-прежнему в области действия , поэтому «list» не возвращается.

Сравните с этим:

{
  LinkedList <Mono> list = new LinkedList ();

  list.add(new Mono (2, 2));
  list.add(new Mono (1, -1));
  list.remove (1);
  list.remove (2);`
}

После закрывающей скобки на «список» больше нельзя ссылаться. «Список» был объявлен внутри этой области, и когда область была закрыта, «список» был удален из пространства имен вместе с самой областью. В этой точке сбор мусора может произойти, поскольку никто не сможет снова использовать «list».

Следите за областью действия ваших объектов. Если вы хотите повлиять на сборку мусора, ограничьте область действия ваших объектов областью, в которой они используются. Как оказалось, это тоже хороший стиль программирования.

0 голосов
/ 08 октября 2011

второй объект будет доступен для сбора gargabe после удаления его из списка, так как на него больше не будет ссылок .. следовательно, он выходит за рамки.

надеюсь, что это помогло

0 голосов
/ 08 октября 2011

Класс "Mono" не может быть выгружен, так как на него все еще есть ссылки.Тип списка ссылается на него, и в списке все еще есть один элемент.

Я полагаю, вы не хотели спрашивать, выгружен ли класс, но является ли экземпляр "выгруженным".Каждый экземпляр класса, каждый объект размещается в куче.Когда объект больше не используется, пространство, которое он занимает в куче, может быть восстановлено.Это не происходит сразу же, однако.Все известные мне реализации JVM используют сборщик мусора для очистки памяти.Чтобы по-настоящему упростить ситуацию: когда больше нет свободного места для создания нового объекта в куче, включается сборщик мусора и проверяет, какие части кучи все еще используются.Детали, которые больше не используются, могут быть повторно использованы для новых объектов.

Таким образом, память от объекта, который больше не используется, будет возвращена, только когда включится сборщик мусора. И это нечто, что нельзя предсказать.

0 голосов
/ 08 октября 2011

Вы имеете в виду, когда Объект выгружен?

Пустой список - это все еще список, поэтому он останется в памяти. Это очищается, когда вы идете:

список = somethingElse;

Это предполагает, что вы не назначаете больше ничего для списка.

Что касается самого определения класса, оно должно оставаться в памяти навсегда. Определения классов находятся в постоянном поколении.

Как примечание. список не может быть мусором в этой точке. Потому что вы можете добавить вещи к нему после того, как очистите его.

...