Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why did switching to from an infinite loop to TimerTask cause this drop in CPU usage?

I wrote a daemon which was structured like this:

while( true ) {
  // do some stuff
  Thread.sleep( 1000 );
}

I noticed it was using a very large amount of CPU - up to 100%. I have had a similar daemon on my production servers for some months with the same CPU problem.

Yesterday I refactored the code to use TimerTask. Immediately I noticed that CPU usage had decreased on my dev box. So I decided to deploy to production and double-check using Munin. Here are the graphs:

Load average

CPU usage

A couple of points:

  • There is absolutely nothing else running on the production server except the JVM.
  • There are no other application threads running
  • It was definitely executing the old-style code at the correct periodic intervals - I always write to the log each time the thread executes.

So: why is Thread.sleep so inefficient compared to TimerTask?

like image 414
netflux Avatar asked Jan 08 '12 08:01

netflux


People also ask

What causes high CPU usage in code?

The common reason for high CPU usage is loop in the code. It could be a loop in the user application or CICS code. Possible causes of a loop that does not terminate are: The termination condition can never occur.

What causes high CPU usage in Java?

Peripheral causes of high Java CPU usagepoorly configured Java GC; issues more correctly attributable to the software stack; thread synchronization, contention and deadlock issues; and. underlying file and database I/O problems.

What is the relationship between timer and TimerTask?

Timer and TimerTask are java util classes that we use to schedule tasks in a background thread. Basically, TimerTask is the task to perform, and Timer is the scheduler.

What is TimerTask?

TimerTask is an abstract class defined in java. util package. TimerTask class defines a task that can be scheduled to run for just once or for repeated number of time. In order to define a TimerTask object, this class needs to be implemented and the run method need to be overridden.


1 Answers

Three possibilities I can think of:

  • You have a huge number of threads doing this, and they're context switching all the time. Using a timer will mean there's only one thread instead. On the other hand, that means you will only get one task executing at a time.
  • You have a continue; statement somewhere in your loop before the sleep, so even if the main body of work of the loop isn't executing very frequently, something is. It's hard to say without seeing some more concrete code though.
  • You have a broken JVM/OS combination. This seems pretty unlikely, admittedly.

A simple loop just executing Thread.sleep(1000) repeatedly should be very cheap - and that should be easy for you to verify, too.

like image 145
Jon Skeet Avatar answered Sep 18 '22 08:09

Jon Skeet