--- old/src/share/vm/memory/genCollectedHeap.cpp 2011-12-06 16:57:21.137839788 -0800 +++ new/src/share/vm/memory/genCollectedHeap.cpp 2011-12-06 16:57:20.914679993 -0800 @@ -1460,26 +1460,26 @@ }; jlong GenCollectedHeap::millis_since_last_gc() { - jlong now = os::javaTimeMillis(); + // os::javaTimeMillis() does not guarantee monotonicity. + jlong now = os::javaTimeNanos() / NANOSECS_PER_MILLISEC; GenTimeOfLastGCClosure tolgc_cl(now); // iterate over generations getting the oldest // time that a generation was collected generation_iterate(&tolgc_cl, false); tolgc_cl.do_generation(perm_gen()); - // XXX Despite the assert above, since javaTimeMillis() - // doesnot guarantee monotonically increasing return - // values (note, i didn't say "strictly monotonic"), - // we need to guard against getting back a time - // later than now. This should be fixed by basing - // on someting like gethrtime() which guarantees - // monotonicity. Note that cond_wait() is susceptible - // to a similar problem, because its interface is - // based on absolute time in the form of the - // system time's notion of UCT. See also 4506635 - // for yet another problem of similar nature. XXX + // XXX Since javaTimeNanos() mostly guarantees monotonically + // increasing return values, depending upon the underlying + // os-dependent implementation, we still need to guard against + // getting back a time later than now. This should be fixed + // by basing the implementation on something like gethrtime() + // which does guarantee monotonicity. + // Note that cond_wait() is susceptible to a similar problem, + // because its interface is based on absolute time in the form + // of the system time's notion of UCT. See also 4506635 for yet + // another problem of similar nature. XXX jlong retVal = now - tolgc_cl.time(); if (retVal < 0) { - NOT_PRODUCT(warning("time warp: %d", retVal);) + NOT_PRODUCT(warning("time warp: "INT64_FORMAT, retVal);) return 0; } return retVal;