mirror of
https://github.com/openjdk/jdk.git
synced 2026-02-16 21:35:25 +00:00
6523160: RuntimeMXBean.getUptime() returns negative values
RuntimeMXBean.getUptime() should be based on HR timers rather than on the OS time Reviewed-by: dholmes, sla
This commit is contained in:
parent
3bffac4b48
commit
db68e03030
@ -103,6 +103,7 @@ SUNWprivate_1.1 {
|
||||
Java_sun_management_VMManagementImpl_getSafepointCount;
|
||||
Java_sun_management_VMManagementImpl_getSafepointSyncTime;
|
||||
Java_sun_management_VMManagementImpl_getStartupTime;
|
||||
Java_sun_management_VMManagementImpl_getUptime0;
|
||||
Java_sun_management_VMManagementImpl_getTotalApplicationNonStoppedTime;
|
||||
Java_sun_management_VMManagementImpl_getTotalClassCount;
|
||||
Java_sun_management_VMManagementImpl_getTotalCompileTime;
|
||||
|
||||
@ -103,6 +103,7 @@ SUNWprivate_1.1 {
|
||||
Java_sun_management_VMManagementImpl_getSafepointCount;
|
||||
Java_sun_management_VMManagementImpl_getSafepointSyncTime;
|
||||
Java_sun_management_VMManagementImpl_getStartupTime;
|
||||
Java_sun_management_VMManagementImpl_getUptime0;
|
||||
Java_sun_management_VMManagementImpl_getTotalApplicationNonStoppedTime;
|
||||
Java_sun_management_VMManagementImpl_getTotalClassCount;
|
||||
Java_sun_management_VMManagementImpl_getTotalCompileTime;
|
||||
|
||||
@ -110,12 +110,7 @@ class RuntimeImpl implements RuntimeMXBean {
|
||||
}
|
||||
|
||||
public long getUptime() {
|
||||
long current = System.currentTimeMillis();
|
||||
|
||||
// TODO: If called from client side when we support
|
||||
// MBean proxy to read performance counters from shared memory,
|
||||
// need to check if the monitored VM exitd.
|
||||
return (current - vmStartupTime);
|
||||
return jvm.getUptime();
|
||||
}
|
||||
|
||||
public long getStartTime() {
|
||||
|
||||
@ -71,6 +71,7 @@ public interface VMManagement {
|
||||
public String getBootClassPath();
|
||||
public List<String> getVmArguments();
|
||||
public long getStartupTime();
|
||||
public long getUptime();
|
||||
public int getAvailableProcessors();
|
||||
|
||||
// Compilation Subsystem
|
||||
|
||||
@ -179,6 +179,10 @@ class VMManagementImpl implements VMManagement {
|
||||
return result;
|
||||
}
|
||||
|
||||
public long getUptime() {
|
||||
return getUptime0();
|
||||
}
|
||||
|
||||
private List<String> vmArgs = null;
|
||||
public synchronized List<String> getVmArguments() {
|
||||
if (vmArgs == null) {
|
||||
@ -192,6 +196,7 @@ class VMManagementImpl implements VMManagement {
|
||||
public native String[] getVmArguments0();
|
||||
|
||||
public native long getStartupTime();
|
||||
private native long getUptime0();
|
||||
public native int getAvailableProcessors();
|
||||
|
||||
// Compilation Subsystem
|
||||
|
||||
@ -78,6 +78,7 @@ typedef enum {
|
||||
JMM_COMPILE_TOTAL_TIME_MS = 8, /* Total accumulated time spent in compilation */
|
||||
JMM_GC_TIME_MS = 9, /* Total accumulated time spent in collection */
|
||||
JMM_GC_COUNT = 10, /* Total number of collections */
|
||||
JMM_JVM_UPTIME_MS = 11, /* The JVM uptime in milliseconds */
|
||||
|
||||
JMM_INTERNAL_ATTRIBUTE_INDEX = 100,
|
||||
JMM_CLASS_LOADED_BYTES = 101, /* Number of bytes loaded instance classes */
|
||||
|
||||
@ -200,6 +200,13 @@ Java_sun_management_VMManagementImpl_getStartupTime
|
||||
JMM_JVM_INIT_DONE_TIME_MS);
|
||||
}
|
||||
|
||||
JNIEXPORT jlong JNICALL
|
||||
Java_sun_management_VMManagementImpl_getUptime0
|
||||
(JNIEnv *env, jobject dummy)
|
||||
{
|
||||
return jmm_interface->GetLongAttribute(env, NULL, JMM_JVM_UPTIME_MS);
|
||||
}
|
||||
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_sun_management_VMManagementImpl_isThreadContentionMonitoringEnabled
|
||||
(JNIEnv *env, jobject dummy)
|
||||
|
||||
@ -33,30 +33,34 @@ import java.lang.management.*;
|
||||
public class UpTime {
|
||||
final static long DELAY = 5; // Seconds
|
||||
final static long TIMEOUT = 30; // Minutes
|
||||
private static RuntimeMXBean metrics
|
||||
final static long MULTIPLIER = 1000; // millisecond ticks
|
||||
|
||||
private static final RuntimeMXBean metrics
|
||||
= ManagementFactory.getRuntimeMXBean();
|
||||
|
||||
public static void main(String argv[]) throws Exception {
|
||||
long jvmStartTime = metrics.getStartTime();
|
||||
long systemStartOuter = System.currentTimeMillis();
|
||||
// this will get an aproximate JVM uptime before starting this test
|
||||
long jvmUptime = System.currentTimeMillis() - jvmStartTime;
|
||||
long systemStartOuter = System_milliTime();
|
||||
long metricsStart = metrics.getUptime();
|
||||
long systemStartInner = System.currentTimeMillis();
|
||||
long systemStartInner = System_milliTime();
|
||||
|
||||
// This JVM might have been running for some time if this test runs
|
||||
// in samevm mode. The sanity check should apply to the test uptime.
|
||||
long testUptime = metricsStart - (systemStartOuter - jvmStartTime);
|
||||
long testUptime = metricsStart - jvmUptime;
|
||||
|
||||
// If uptime is more than 30 minutes then it looks like a bug in
|
||||
// the method
|
||||
if (testUptime > TIMEOUT * 60 * 1000)
|
||||
if (testUptime > TIMEOUT * 60 * MULTIPLIER)
|
||||
throw new RuntimeException("Uptime of the JVM is more than 30 "
|
||||
+ "minutes ("
|
||||
+ (metricsStart / 60 / 1000)
|
||||
+ (metricsStart / 60 / MULTIPLIER)
|
||||
+ " minutes).");
|
||||
|
||||
// Wait for DELAY seconds
|
||||
Object o = new Object();
|
||||
while (System.currentTimeMillis() < systemStartInner + DELAY * 1000) {
|
||||
while (System_milliTime() < systemStartInner + DELAY * MULTIPLIER) {
|
||||
synchronized (o) {
|
||||
try {
|
||||
o.wait(DELAY * 1000);
|
||||
@ -67,23 +71,27 @@ public class UpTime {
|
||||
}
|
||||
}
|
||||
|
||||
long systemEndInner = System.currentTimeMillis();
|
||||
long systemEndInner = System_milliTime();
|
||||
long metricsEnd = metrics.getUptime();
|
||||
long systemEndOuter = System.currentTimeMillis();
|
||||
long systemEndOuter = System_milliTime();
|
||||
|
||||
long systemDifferenceInner = systemEndInner - systemStartInner;
|
||||
long systemDifferenceOuter = systemEndOuter - systemStartOuter;
|
||||
long metricsDifference = metricsEnd - metricsStart;
|
||||
|
||||
// Check the flow of time in RuntimeMXBean.getUptime(). See the
|
||||
// picture below
|
||||
if (metricsDifference < systemDifferenceInner)
|
||||
// picture below.
|
||||
// The measured times can be off by 1 due to conversions from
|
||||
// nanoseconds to milliseconds, using different channels to read the
|
||||
// HR timer and rounding error. Bigger difference will make the test
|
||||
// fail.
|
||||
if (metricsDifference - systemDifferenceInner < -1)
|
||||
throw new RuntimeException("Flow of the time in "
|
||||
+ "RuntimeMXBean.getUptime() ("
|
||||
+ metricsDifference + ") is slower than "
|
||||
+ " in system (" + systemDifferenceInner
|
||||
+ ")");
|
||||
if (metricsDifference > systemDifferenceOuter)
|
||||
if (metricsDifference - systemDifferenceOuter > 1)
|
||||
throw new RuntimeException("Flow of the time in "
|
||||
+ "RuntimeMXBean.getUptime() ("
|
||||
+ metricsDifference + ") is faster than "
|
||||
@ -92,6 +100,10 @@ public class UpTime {
|
||||
|
||||
System.out.println("Test passed.");
|
||||
}
|
||||
|
||||
private static long System_milliTime() {
|
||||
return System.nanoTime() / 1000000; // nanoseconds / milliseconds;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user