Hello all,
I came across an interesting article in "The Well-Grounded Java Developer" (6.4.2, pg. 164), describing how the System.nanoTime() can vary from the wall clock over longer periods of time (4-7 minute intervals) on certain OS (Linux, OSX). The author argues that System.nanoTime() uses Time Stamp Counter:
"This brings us to the most widely used modern counter—Time Stamp Counter
(TSC). This is basically a CPU counter that tracks how many cycles the CPU has run. At
first glance this seems ideal as a clock. But this counter is per-CPU and can potentially
be affected by power saving and other factors at runtime. This means that different
CPUs can drift away from each other and from wall-clock time."
- "The Well-Grounded Java Developer" (6.4.2, pg. 164)
He then demonstrates this on Linux and Solaris, and argues the difference from wall clocks occurs due to the JVM occasionally shifting processing of a thread between CPU's cores. During each CPU shift, the System.nanoTime measurements will show a large jump in nanosecond difference from the wall clock, since each CPU has slightly difference TSC value.
To reproduce this, see the code sample here:
http://goo.gl/yiBFm, on running this code on OSX, that drift was observable after just 4-7 minutes.
The author suggests, that for longer interval measurements, nanosecond time should be rebased against currentTimeMillis().
Would some way to rebase nano time worth adding? Or perhaps a caveat that longer measurements are subject to such issues?
Thanks,
Nigel Thomas