-
Bug
-
Resolution: Fixed
-
P2
-
1.3.1
-
rc1
-
x86
-
windows_2000
-
Verified
Issue | Fix Version | Assignee | Priority | Status | Resolution | Resolved In Build |
---|---|---|---|---|---|---|
JDK-2041654 | 1.4.0 | John Coomes | P2 | Closed | Fixed | beta |
Name: boT120536 Date: 03/20/2001
java version "1.3.1-beta"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.1-beta-b15)
Java HotSpot(TM) Client VM (build 1.3.1beta-b15, interpreted mode)
Problem:
I have a test with the following :
C1 ---So1----> O1
|
St1
|
V
C2 ---So2-----> O2
C1, C2 2 entries in a cache, in an array...
O1, O2 2 objects
So1, So2 2 Soft References
St1 1 Strong Reference
I have output showing, that the GC cleans So2 (sets the referent to null)
but with keeping So1 and St1 alive.
The problem is that So2 should be remove (referent cleaned) only if O2 is
garbage collected...
It is always reproductible and always with the same output...
1- STEPS
Compile and run
2- CODE:
import java.lang.ref.SoftReference;
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
class Main {
static int size = 100000;
public static void main(String[] args) {
CachedReference1[] cra1 = new CachedReference1[size];
CachedReference2[] cra2 = new CachedReference2[size];
ReferenceQueue rq = new ReferenceQueue();
for (int i = 0; i < size; i++) {
MyObject2 o2 = new MyObject2(i);
MyObject1 o1 = new MyObject1(o2, i);
cra2[i] = new CachedReference2(o2, rq);
cra1[i] = new CachedReference1(o1);
Reference ref;
while ((ref = rq.poll()) != null) {
MyObject1 mo1 = (MyObject1) cra1[((CachedReference2)
ref).id].get();
if (mo1 != null) {
MyObject2 mo2 = mo1.ref;
System.out.println("bug: "+((CachedReference2) ref).id+"
ref: "+mo2);
}
}
}
}
}
class MyObject1 {
int id;
MyObject2 ref;
MyObject1(MyObject2 ref_, int id_) {
ref = ref_;
id = id_;
}
}
class MyObject2 {
int id;
MyObject2(int id_) {
id = id_;
}
}
class CachedReference1 extends SoftReference {
int id;
CachedReference1(MyObject1 o1) {
super(o1);
id = o1.id;
}
}
class CachedReference2 extends SoftReference {
int id;
CachedReference2(MyObject2 o2, ReferenceQueue rq) {
super(o2, rq);
id = o2.id;
}
}
3 - OUTPUT
should be empty but I have:
bug: 1240 ref: MyObject2@273d3c
4 - TRACE
N/A
5 - ADDITIONAL INFO
It's working fine with 1.3 client/server, 1.3.1 server:
java version "1.3.0_02"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.0_02)
Java HotSpot(TM) Server VM (build 2.0fcs-E, mixed mode)
java version "1.3.0_02"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.0_02)
Java HotSpot(TM) Client VM (build 1.3.0_02, mixed mode)
java version "1.3.1-beta"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.1-beta-b15)
Java HotSpot(TM) Server VM (build 1.3.1beta-b15, interpreted mode)
But I suspect it can also happens (but I was not able to proove it with a simple test)
(Review ID: 119114)
======================================================================
java version "1.3.1-beta"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.1-beta-b15)
Java HotSpot(TM) Client VM (build 1.3.1beta-b15, interpreted mode)
Problem:
I have a test with the following :
C1 ---So1----> O1
|
St1
|
V
C2 ---So2-----> O2
C1, C2 2 entries in a cache, in an array...
O1, O2 2 objects
So1, So2 2 Soft References
St1 1 Strong Reference
I have output showing, that the GC cleans So2 (sets the referent to null)
but with keeping So1 and St1 alive.
The problem is that So2 should be remove (referent cleaned) only if O2 is
garbage collected...
It is always reproductible and always with the same output...
1- STEPS
Compile and run
2- CODE:
import java.lang.ref.SoftReference;
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
class Main {
static int size = 100000;
public static void main(String[] args) {
CachedReference1[] cra1 = new CachedReference1[size];
CachedReference2[] cra2 = new CachedReference2[size];
ReferenceQueue rq = new ReferenceQueue();
for (int i = 0; i < size; i++) {
MyObject2 o2 = new MyObject2(i);
MyObject1 o1 = new MyObject1(o2, i);
cra2[i] = new CachedReference2(o2, rq);
cra1[i] = new CachedReference1(o1);
Reference ref;
while ((ref = rq.poll()) != null) {
MyObject1 mo1 = (MyObject1) cra1[((CachedReference2)
ref).id].get();
if (mo1 != null) {
MyObject2 mo2 = mo1.ref;
System.out.println("bug: "+((CachedReference2) ref).id+"
ref: "+mo2);
}
}
}
}
}
class MyObject1 {
int id;
MyObject2 ref;
MyObject1(MyObject2 ref_, int id_) {
ref = ref_;
id = id_;
}
}
class MyObject2 {
int id;
MyObject2(int id_) {
id = id_;
}
}
class CachedReference1 extends SoftReference {
int id;
CachedReference1(MyObject1 o1) {
super(o1);
id = o1.id;
}
}
class CachedReference2 extends SoftReference {
int id;
CachedReference2(MyObject2 o2, ReferenceQueue rq) {
super(o2, rq);
id = o2.id;
}
}
3 - OUTPUT
should be empty but I have:
bug: 1240 ref: MyObject2@273d3c
4 - TRACE
N/A
5 - ADDITIONAL INFO
It's working fine with 1.3 client/server, 1.3.1 server:
java version "1.3.0_02"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.0_02)
Java HotSpot(TM) Server VM (build 2.0fcs-E, mixed mode)
java version "1.3.0_02"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.0_02)
Java HotSpot(TM) Client VM (build 1.3.0_02, mixed mode)
java version "1.3.1-beta"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.1-beta-b15)
Java HotSpot(TM) Server VM (build 1.3.1beta-b15, interpreted mode)
But I suspect it can also happens (but I was not able to proove it with a simple test)
(Review ID: 119114)
======================================================================
- backported by
-
JDK-2041654 Regression: SoftReferences put in the queue before the referent is collected
-
- Closed
-