Производительность сбрасываемого таймера в Java

При профилировании своего приложения я обнаружил источник частого выделения ... Я использую несколько таймеров для проверки тайм-аутов (~ 2 мс, зависит от состояния приложения).

Согласно этому ответу SO, ScheduledThreadPoolExecutor предпочтительнее Timer. Итак, я сделал класс очень похожим на этот другой ответ SO, который планирует задачи в соответствии с рекомендациями. Пользуюсь так:

private final ResettableTimer timer = new ResettableTimer(new Runnable() {
    public void run() {
        //timeout, do something
    }
});

timer.reset(2, TimeUnit.MILLISECONDS);

Я обнаружил, что каждый раз при планировании задачи java выделяет следующее:

java.util.concurrent.LinkedBlockingQueue$Node - 16 байтов java.util.concurrent.Executors$RunnableAdapter - 16 байтов java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask - 64 байта java.util.concurrent.locks.AbstractQueuedSynchronizer$node - 28 байтов

Например: 2 таймера на 500 задач / с = 124 КБ / с.

Это мало, но вызывает очень частую сборку мусора. Похоже, что сейчас это не вызывает у меня проблем, хотя может быть причиной некоторого заикания, которое я наблюдаю на старых устройствах. Я должен беспокоиться?

Что еще более важно, эти распределения кажутся совершенно ненужными, поскольку эти задачи повторяют одно и то же снова и снова. Есть ли способ избежать этого перераспределения?


person firyice    schedule 29.10.2013    source источник
comment
Смысл запланированного исполнителя заключается в том, что он позволяет вам запланировать выполнение отдельной задачи с фиксированными интервалами. Если вы используете его для переназначения одной и той же задачи каждые 2 мс, вы используете его почти как простой исполнитель. 124k / s - это мелочь на настольной виртуальной машине, но, возможно, gc Android не так эффективен для недолговечных объектов.   -  person vanza    schedule 29.10.2013
comment
@vanza Я использую запланированный исполнитель, чтобы я мог вызвать ScheduledExecutorService.Schedule, чтобы запланировать мой тайм-аут Runnable with a delay. Не лучше ли сразу использовать ExecutorService.submit и sleep ()?   -  person firyice    schedule 29.10.2013
comment
Я имею в виду, что вы должны планировать задачи с задержкой и периодом, если можете; таким образом вы повторно используете одну и ту же задачу для каждого выполнения, вместо того, чтобы планировать новую задачу каждые 2 мс.   -  person vanza    schedule 29.10.2013
comment
@vanza К сожалению, в моем случае нет установленного периода. Время меняется в зависимости от состояния приложения и от того, истек ли мой последний таймер. Я попытался уточнить это в своем вопросе ... (~ 2 мс, зависит от состояния приложения)   -  person firyice    schedule 29.10.2013