Java: Почему это не собирать мусор? - PullRequest
21 голосов
/ 20 апреля 2009

Быстрый вопрос по теории GCing. У меня есть следующий метод. Он запускается и выходит из метода. Почему даже после запуска GC таймер все еще существует и продолжает работать? Я не верю, что после появления этого метода все еще есть ссылка на таймер или таймерную задачу, поэтому я ожидал, что таймер будет GCed и вызовет исключение. Пожалуйста, помогите мне понять эту концепцию.

Спасибо, JBU

private void startTimer()
    {
        Timer timer= new Timer();
        TimerTask timerTask= new TimerTask()
        {

            @Override
            public void run()
            {
                System.out.println("TICK");
            }
        };

        timer.scheduleAtFixedRate(timerTask,
                0,
                500);
    }

Ответы [ 4 ]

34 голосов
/ 20 апреля 2009

Объект Timer фактически планирует задачи, выполняемые в фоновом потоке, так что фоновый поток поддерживает ссылку на Timer (и TimerTask), что предотвращает сбор обоих мусоров. *

Вот соответствующая цитата из документов:

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

Таким образом, условие «выполнение всех невыполненных задач завершено» не выполняется, и поток никогда не завершается, поэтому Timer / TimerTask никогда не выполняется GC'd.

12 голосов
/ 20 апреля 2009

Поскольку у таймера есть фоновый поток, который продолжает работать :

Каждый объект таймера соответствует один фоновый поток, который используется для выполнения всех таймера задачи, последовательно. Таймер задач должно завершиться быстро. Если таймер задача занимает слишком много времени для выполнения, он "затягивает" выполнение задачи таймера нить. Это может, в свою очередь, задержать выполнение последующих задач, которые может "сгруппироваться" и выполнить быстро правопреемство, когда (и если) нарушителя задание наконец завершено.

Поскольку это фоновый поток, он продолжается до выхода из JVM или до его остановки.

Обновление: немного больше об этом. «Фоновый поток» - это то же самое, что и поток демона, названный по аналогии с процессом демона BSD. Если вы увидите javadocs на Thread , вы найдете:

Отмечает эту ветку как демон поток или пользовательский поток. Ява Виртуальная машина выходит, когда только все потоки - это демон резьб.

Когда ваш основной завершает работу, все пользовательские потоки останавливаются, оставляя только потоки демонов. Затем JVM выключается. Для хорошего времени - если коротко - звоните Thread.currentThread().setDaemon(true); с основного.

Обновление: Ack. У меня было это почти право. Вы должны сделать таймер демоном во время строительства. (Это изменилось, или у меня просто произошел мозговой сбой?)

В любом случае, вот пример кода:

import java.util.*;

class Chatter extends TimerTask {
    public void run(){
        System.err.println("Timer run.");
    }
}

public class TryThread {
    public static void main(String[] argv){
        // If argument is true, only runs a few times.
        Timer t = new Timer(false);
        t.schedule(new Chatter(), 1L, 1L);
        return ;
    }
}
2 голосов
/ 20 апреля 2009

Таймер не является сборщиком мусора, потому что он все еще работает - какой-то другой объект (например, планировщик потока) все еще имеет ссылку на него, который, вероятно, был создан внутри scheduleAtFixedRate().

0 голосов
/ 20 апреля 2009

Откуда ты знаешь, что GC побежал? Сборка мусора вообще не является детерминированной вещью, и она определенно не вызвана областью действия метода. Это не похоже на C ++, где вы покидаете область действия функции и деструкторы запускаются. Он будет собирать эту память, если и когда GC захочет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...