Я проходил собеседование и интервьювер задал вопрос, можно ли убить GC в Java. На дополнительный вопрос, должно ли жить приложение он ответил, да должно. Я сказал, что без пересобирания JDK это сделать нельзя, точнее какие-то догадки я построил, но чтобы приложение работало, я не знаю как это сделать. Интервьювер сказал, что можно и что нужно загуглить, в гугл ничего такого не нашел, пожалуйста подскажите.
No. You cannot kill a GC programmatically. The interviewer is expecting some answer like:
The garbage collection cannot be forced. The garbage collector runs in low memory situations. When it runs, it releases the memory allocated by an unreachable object. The garbage collector runs on a low priority daemon (background) thread. You can nicely ask the garbage collector to collect garbage by calling System.gc() but you can�t force it.
Note: The only way you kill a GC is when you exit your application. System.exit();
Нет. Вы не можете убить GC из кода. Интервьюер ждал ответ типо такого:
GC не возможно остановить. Он начинает работу когда остается мало памяти. Начиная работать он освобождает память от забытых (недостежимых, тех на которые не осталось ссылок) объектов. GC работает в потоке демона с низким приоритетом. Единственное, что вы можете - попросите его собрать мусор вызовом System.gc(), но остановить вы его не можете.
p.s. Хотя можете, используя одну секретную команду от гуру-разработки System.exit();
исходник
Это единственное, что смог найти.
IMHO: GC включается когда остается мало память. Если программа не использует всю память, то он не начнет работать, можно сказать, что он мертв, но это не так. А если все такие его неведомым образом убить, то узнаете вы это по OutOfMemoryError и приложение остановится
По следам идеи @ViacheslavVedenin, что будет с GC если в finalize
По докам написал сам @ViacheslavVedenin, а я решил пойти путем экспериментов. И никакой разницы.
лог нормальной работы
лог с Thread.currentThread().stop();
в finalize
лог с while(true);
лог с throw new RuntimeException();
в finalize
Если честно то особой разницы я не заметил, так, что думаю GC создавая новую нить для finalize не особо о ней заботиться и не следит. Когда она закончит работу объект будет удален. Причина по который нить завершиться его не волнуют, раз завершилась значит сделала все, что могла.
Добавлю так же ответы товарища @Suvitruf, чтобы заметнее были:
Можно (правда не убить, а заставить выкинуть OutOfMemory и прекратить сборку мусора, при этом приложение сможет продолжить работу), вот пример:
import java.io.IOException;
public class Test1 {
private static class TestClass {
private byte[] bytes = new byte[100000];
public int i = 0;
public static volatile boolean flag = true;
protected void finalize() throws IOException {
int i = 1;
while (flag) {
i++;
}
}
}
public static void main(String[] args) throws InterruptedException {
TestClass t1 = new TestClass();
new Test1().test(0, t1);
}
private void test(int j, TestClass t1) throws InterruptedException {
try {
for (int i = 1; i <= 100000; i++) {
TestClass t = new TestClass();
System.out.println(i);
}
} catch (OutOfMemoryError e) {
j++;
t1.i = j;
System.out.println("I alive!!! " + t1.i);
if( j > 100) {
TestClass.flag = false;
}
test(j, t1);
}
}
}
Что тут происходит? По спецификации, сборщик должен выполнить finalize
перед тем как удалять объекты, из-за бесконечного цикла finalize
, он не сможет удалять объекты и начнет выкидывать OutOfMemoryError (впрочем можно просто использовать вечные ссылки на объекты). При этом новые объекты создавать не получится, но можно продолжать работать со старыми и стеком (см код в catch (OutOfMemoryError e)). В том числе переиспользовать уже существующие объекты, например сохранять новые данные в старых объектах (можно даже написать свои аналоги сишных new и delete, используя массивы байт как хранилище данных и "сериализованных" объектов).
Через какое-то время мы отключаем бесконечный цикл в финалайзерах и у нас сборка мусора и создание объектов выполняется как обычно.
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
как можно строку или набор charов состоящую из 0 и 1 перевести в boolean?Вроде в с++ это было легко сделать,тк
Есть text view, как в него вывести дату и время в милли секундах, и можно ли вывести не дату устройства а unix ?
Пытаюсь в проект для Android Studio добавить эту библиотеку: https://githubcom/kochedykov/jlibmodbus
Gradle в Android Studio не собирает проект, ругается на ошибку в коде, где стоит аннотация Suppress WarningsЧто делать?