1

When profiling my app, I found a source of frequent allocations... I am utilizing multiple timers to check for timeouts (~2ms, varies with app state).

According to this SO answer, ScheduledThreadPoolExecutor is preferable to Timer. So, I made class very similar to this other SO answer that schedules tasks as recommended. I use it like so:

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

timer.reset(2, TimeUnit.MILLISECONDS);

I found that every time a task is scheduled, java allocates the following:

java.util.concurrent.LinkedBlockingQueue$Node - 16 bytes java.util.concurrent.Executors$RunnableAdapter - 16 bytes java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask - 64 bytes java.util.concurrent.locks.AbstractQueuedSynchronizer$node - 28 bytes

For example: 2 timers at 500 tasks/s = 124kB/s

This is small, but it causes very frequent garbage collection. It doesn't seem to be causing me problems right now, although it may be the cause of some stuttering I'm seeing on older devices. Should I be worried?

More importantly, these allocations seem pretty unnecessary since these tasks are doing the same thing over & over again. Is there any way to avoid this re-allocation?

Community
  • 1
  • 1
firyice
  • 527
  • 7
  • 24
  • The point of a scheduled executor is that it allows you to scheduled a single task to run at fixed intervals. If you're using it to re-schedule the same task every 2ms, you're using it almost as a plain executor. 124k/s is peanuts on a desktop VM, but maybe android's gc isn't that efficient for short-lived objects. – vanza Oct 29 '13 at 03:00
  • @vanza I'm using a scheduled executor so that I can call `ScheduledExecutorService.Schedule` to schedule my timeout Runnable with a delay. Is it better to just use `ExecutorService.submit` and sleep() immediately? – firyice Oct 29 '13 at 03:06
  • I mean you should schedule tasks with a delay and period if you can; that way you re-use the same task for every execution, instead of having to schedule a new one every 2ms. – vanza Oct 29 '13 at 03:11
  • @vanza Unfortunately, there is no set period in my case. Timing changes depending upon app state, and whether my last timer timed-out. I tried to clarify this in my question... *(~2ms, varies with app state)* – firyice Oct 29 '13 at 03:15

0 Answers0