При профилировании своего приложения я обнаружил источник частого выделения ... Я использую несколько таймеров для проверки тайм-аутов (~ 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 КБ / с.
Это мало, но вызывает очень частую сборку мусора. Похоже, что сейчас это не вызывает у меня проблем, хотя может быть причиной некоторого заикания, которое я наблюдаю на старых устройствах. Я должен беспокоиться?
Что еще более важно, эти распределения кажутся совершенно ненужными, поскольку эти задачи повторяют одно и то же снова и снова. Есть ли способ избежать этого перераспределения?
ScheduledExecutorService.Schedule
, чтобы запланировать мой тайм-аут Runnable with a delay. Не лучше ли сразу использоватьExecutorService.submit
и sleep ()? - person firyice   schedule 29.10.2013