JDK-6990442 : (ref) Regression to clearing of a softly reachable object
  • Type: Enhancement
  • Component: hotspot
  • Sub-Component: gc
  • Affected Version: 6u14
  • Priority: P3
  • Status: Open
  • Resolution: Unresolved
  • OS: generic
  • CPU: generic
  • Submitted: 2010-10-07
  • Updated: 2019-02-11
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Related Reports
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Behavior change since 6u14.  The GC decides not to clear the SoftReference but 
an object in the reference chain of that SoftReference is being cleared.

Below is the test program showing the problem. Specifically,
o2 is only reachable via s2 (SoftReference) and s2 is not cleared
and thus w2.get() should return non-null.

import java.lang.ref.*;
import java.util.*;

public class RefCompliance {
    RefCompliance () {

    public static void test() {

        int[] o1 = new int[10];

        WeakReference w1 = new WeakReference(o1);
        SoftReference s1 = new SoftReference(w1);

        int[] o2 = new int[10];

        WeakReference w2 = new WeakReference(o2);
        SoftReference s2 = new SoftReference(w2);

        int[] o3 = new int[10];

        WeakReference w3 = new WeakReference(o3);

        o1 = null;
        o2 = null;
        o3 = null;
        w2 = null;

        // Scrub stack because of conservative collector
        int[] dummy1 = new int[10];
        int[] dummy2 = new int[10];


        int res1;

        w2 = (WeakReference)s2.get();
        if (w1 == s1.get()) {
            res1 = 0;
            if (w1.get() == null) {
                res1 += 100;
            if (w2.get() == null) {
                res1 += 10;
            if (w3.get() == null) {
                res1 += 1;
        } else {
            res1 = -1;

        if (res1 == 101) {
        } else if (res1 == 111) {
            System.err.println("weakest link on strongest chain");
        } else if (res1 == 001) {
            System.err.println("API spec");
        } else {
            System.err.println("unknown: result " + res1);

    public static void main(String[] args) {

$ /java/re/jdk/6u13/latest/binaries/solaris-i586/bin/java RefCompliance

$ /java/re/jdk/6u14/latest/binaries/solaris-i586/bin/java RefCompliance
weakest link on strongest chain
weakest link on strongest chain
weakest link on strongest chain
weakest link on strongest chain
weakest link on strongest chain

Release team: Approved for deferral from JDK 8 to 8-pool. Given the scope of this change it may be worth changing this from Bug to Enhancement.

SQE: No objections to defer this complicated fix.

8-defer-request-justification This is a large change and requires a lot of work an testing. The risk of trying to fix this late in the JDK8 release is high.

This is a complex project to get right. There is a JEP out for discussions around this topic: http://openjdk.java.net/jeps/134

EVALUATION This regression in fact has a side effect of giving the new intuitive semantics for soft references as described in: 6990438: (ref) Soft reference could consider strong if GC decides not to clear in the stop-the-world collectors but not CMS and G1. Making CMS and G1 to give the new intuitive semantics will fix the hotspot side for 6990438.

SUGGESTED FIX <deleted>; see evaulation for the latest status of this.

EVALUATION We are discussing how best to address this going forward.