Issue | Fix Version | Assignee | Priority | Status | Resolution | Resolved In Build |
---|---|---|---|---|---|---|
JDK-8065492 | 8u45 | Ivan Gerasimov | P4 | Resolved | Fixed | b01 |
JDK-8064410 | 8u40 | Ivan Gerasimov | P4 | Resolved | Fixed | b15 |
JDK-8070043 | emb-8u47 | Ivan Gerasimov | P4 | Resolved | Fixed | team |
java version "1.6.0_10"
Java(TM) SE Runtime Environment (build 1.6.0_10-b33)
Java HotSpot(TM) Client VM (build 11.0-b15, mixed mode, sharing)
java version "1.7.0-ea-fastdebug"
Java(TM) SE Runtime Environment (build 1.7.0-ea-fastdebug-b58)
Java HotSpot(TM) Client VM (build 16.0-b02-fastdebug, mixed mode)
A DESCRIPTION OF THE PROBLEM :
ReferenceQueue.remove(timeout) may return null even if given timeout period has not expired.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
ReferenceQueue.remove(timeout) should wait until either next reference object in this queue becomes available or the given timeout period expires, but not earlier or far later.
ACTUAL -
Exception in thread "main" java.lang.Error: timeout: 5000; actual time: 1000
at Main.main(Main.java:38)
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
public class Main extends Thread {
static ReferenceQueue<Object> queue = new ReferenceQueue<Object>();
static Object referent = new Object();
static WeakReference<Object> reference = new WeakReference<Object>(referent, queue);
long timeout;
long actual;
boolean suspect;
Main(long timeout) {
this.timeout = timeout;
}
public static void main(String... args) throws Exception {
final int LONG_TIMEOUT = 5000;
final int SHORT_WAIT_TIME = 1000;
final int TOLERANCE = 1000;
assert LONG_TIMEOUT > SHORT_WAIT_TIME : "Bad initial parameters";
assert LONG_TIMEOUT - SHORT_WAIT_TIME > TOLERANCE : "Bad initial parameters";
Main[] threads = new Main[2];
for (int i = 0, n = threads.length; i < n; ++i) {
threads[i] = new Main(LONG_TIMEOUT);
threads[i].start();
}
Thread.sleep(SHORT_WAIT_TIME);
referent = null;
System.gc();
for (Main thread : threads) {
thread.join();
}
for (Main thread : threads) {
if (thread.suspect && Math.abs(thread.timeout - thread.actual) > TOLERANCE) {
throw new Error("timeout: " + thread.timeout + "; actual time: " + thread.actual);
}
}
}
public void run() {
try {
long start = System.currentTimeMillis();
Reference<?> reference = queue.remove(timeout);
actual = System.currentTimeMillis() - start;
suspect = reference == null;
} catch (InterruptedException exc) {
exc.printStackTrace();
}
}
}
---------- END SOURCE ----------
- backported by
-
JDK-8064410 (ref) ReferenceQueue.remove(timeout) may return null even if timeout has not expired
-
- Resolved
-
-
JDK-8065492 (ref) ReferenceQueue.remove(timeout) may return null even if timeout has not expired
-
- Resolved
-
-
JDK-8070043 (ref) ReferenceQueue.remove(timeout) may return null even if timeout has not expired
-
- Resolved
-
- relates to
-
JDK-8016643 ReferenceQueue.remove(timeout) may wait too long
-
- Closed
-
-
JDK-8051843 Public API alternative for sun.misc.Cleaner
-
- Closed
-
-
JDK-8038333 TEST_BUG: java/lang/ref/EarlyTimeout.java fails with a non-adequate message
-
- Closed
-
-
JDK-8038982 java/lang/ref/EarlyTimeout.java: elapsed time 981 is less than timeout 1000
-
- Closed
-