как уничтожить объект в Java?

я столкнулся с этим вопросом в интервью со следующими вариантами:

Как уничтожить объект в Java?

a. System.gc();  
b. Runtime.getRuntime.gc();  
c. object.delete();  
d. object.finalize();  
e. Java performs gc by itself, no need to do it manually.
  1. ответ должен быть e?

  2. что, если e там не было? тогда ? явно не ответ. a и b будут делать gc для всего приложения(вопрос требует для одного объекта). Я думаю, что это d, потому что finalize() вызывается непосредственно перед gc(но необходимо, чтобы после finalize вызывается gc ? или я ошибаюсь ? е должен быть там, чтобы ответить на этот вопрос ?

6 ответов


ответ E-правильный ответ. Если E нет, у вас скоро закончится память (или) не будет правильного ответа.

объект должен быть недоступен, чтобы иметь право на GC. JVM будет выполнять несколько сканирований и перемещение объектов из одного поколения в другое поколение, чтобы определить приемлемость GC и освобождает память, когда объекты недоступны.


разъяснить, почему другие ответы не могут работать:

  1. System.gc() (вместе с Runtime.getRuntime().gc(), который делает то же самое) подсказки что вы хотите уничтожить вещи. Неясно. JVM может игнорировать запросы на запуск цикла GC, если он не видит необходимости в этом. Кроме того, если вы не обнулили все доступные ссылки на объект, GC все равно его не коснется. Так что A и B дисквалифицированы.

  2. Runtime.getRuntime.gc() is плохая грамматика. getRuntime - это функция, а не переменная; вам нужны скобки после нее, чтобы вызвать ее. Итак, Б дважды дисквалифицирован.

  3. Object нет delete метод. Поэтому C дисквалифицирован.

  4. пока Object тут есть finalize метод, он ничего не уничтожает. только сборщик мусора может фактически удалить объект. (и во многих случаях, они технически даже не удосужились сделать это; они просто не копируют его, когда делают другие, поэтому он остается позади.) Все finalize дает ли объект шанс очистить до JVM отбрасывает его. Более того, вы никогда не должны звонить finalize напрямую. (As finalize защищен, JVM не позволит вам вызвать его на произвольный объект в любом случае. Итак, D дисквалифицирован.

  5. кроме того, object.doAnythingAtAllEvenCommitSuicide() требует, чтобы запущенный код имел ссылку на object. Только это делает его "живым" и, следовательно, не пригодным для сбора мусора. Так что C и D дважды дисквалифицированы.


Короткий Ответ-E

ответE учитывая, что остальные явно ошибаются, но ..

длинный ответ - это не так просто; это зависит ...

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

в следующей статье есть много хороших деталей о том, как работает управление памятью и не работает, и что получает занять чем. как работают сборщики мусора поколения и Спасибо за память (понимание того, как JVM использует собственную память в Windows и Linux )

если Вы читаете ссылки, я думаю, вы получите идею, что управление памятью в Java не так просто, как вопрос с множественным выбором.


значение null. Тогда ссылок больше нет, и объект станет пригодным для сборки мусора. GC автоматически удалит объект из кучи.


вот код:

public static void main(String argso[]) {
int big_array[] = new int[100000];

// Do some computations with big_array and get a result. 
int result = compute(big_array);

// We no longer need big_array. It will get garbage collected when there
// are no more references to it. Since big_array is a local variable,
// it refers to the array until this method returns. But this method
// doesn't return. So we've got to explicitly get rid of the reference
// ourselves, so the garbage collector knows it can reclaim the array. 
big_array = null;

// Loop forever, handling the user's input
for(;;) handle_input(result);
}

в java нет явного способа выполнения сборки мусора. Сам JVM запускает некоторые потоки в фоновом режиме, проверяя объекты, которые не имеют никаких ссылок, что означает, что все способы доступа к объекту потеряны. С другой стороны, объект также имеет право на сборку мусора, если он выходит за рамки программы, в которой мы создали объект, завершается или заканчивается. Подходя к вашему вопросу, метод finalize такой же, как деструктор в С.++ Метод finalize фактически вызывается непосредственно перед моментом очистки памяти объекта JVM. Это до вас, чтобы определить метод finalize или нет в вашей программе. Однако, если сборка мусора объекта выполняется после завершения программы, JVM не будет вызывать метод finalize, который вы определили в своей программе. Вы можете спросить, Что такое использование метода finalize? Например, давайте рассмотрим, что вы создали объект, который требует некоторого поток внешний файл, и вы явно определили метод finalize для этого объекта, который проверяет, открыт ли поток в файл или нет, и если нет, он закрывает поток. Предположим, после написания нескольких строк кода Вы потеряли ссылку на объект. Тогда он имеет право на сбор мусора. Когда JVM собирается освободить пространство вашего объекта, JVM просто проверяет, определили ли вы метод finalize или нет и вызывает метод, поэтому нет риска открытого потока. метод finalize make программа безрисковая и более надежная.