1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
|
/* Verify that libffi closures aren't deallocated too early.
Copyright (C) 2007 Free Software Foundation, Inc
Contributed by Alexandre Oliva <aoliva@redhat.com>
If libffi closures are released too early, we lose.
*/
import java.util.HashSet;
public class TestClosureGC {
public static String objId (Object obj) {
return obj + "/"
+ Integer.toHexString(obj.getClass().getClassLoader().hashCode());
}
public static class cld extends java.net.URLClassLoader {
static final Object obj = new cl0();
public cld () throws Exception {
super(new java.net.URL[] { });
/* System.out.println (objId (this) + " created"); */
}
public void finalize () {
/* System.out.println (objId (this) + " finalized"); */
}
public String toString () {
return this.getClass().getName() + "@"
+ Integer.toHexString (hashCode ());
}
public Class loadClass (String name) throws ClassNotFoundException {
try {
java.io.InputStream IS = getSystemResourceAsStream
(name + ".class");
int maxsz = 1024, readsz = 0;
byte buf[] = new byte[maxsz];
for(;;) {
int readnow = IS.read (buf, readsz, maxsz - readsz);
if (readnow <= 0)
break;
readsz += readnow;
if (readsz == maxsz) {
byte newbuf[] = new byte[maxsz *= 2];
System.arraycopy (buf, 0, newbuf, 0, readsz);
buf = newbuf;
}
}
return defineClass (name, buf, 0, readsz);
} catch (Exception e) {
return super.loadClass (name);
}
}
}
public static class cl0 {
public cl0 () {
/* System.out.println (objId (this) + " created"); */
}
public void finalize () {
/* System.out.println (objId (this) + " finalized"); */
}
}
public static class cl1 {
final HashSet hs;
static final Object obj = new cl0();
public cl1 (final HashSet hs) {
this.hs = hs;
/* System.out.println (objId (this) + " created"); */
}
public void finalize () {
/* System.out.println (objId (this) + " finalized"); */
}
}
public static class cl2 {
final HashSet hs;
static final Object obj = new cl0();
public cl2 (final HashSet hs) {
this.hs = hs;
/* System.out.println (objId (this) + " created"); */
}
public void finalize () {
/* System.out.println (objId (this) + " finalized"); */
hs.add(this);
hs.add(new cl0());
}
}
static final HashSet hs = new HashSet();
static final Object obj = new cl0();
public static void main(String[] argv) throws Exception {
{
Class[] hscs = { HashSet.class };
Object[] hsos = { hs };
new cld().loadClass ("TestClosureGC$cl1").
getConstructor (hscs).newInstance (hsos);
new cld().loadClass ("TestClosureGC$cl2").
getConstructor (hscs).newInstance (hsos);
new cld().loadClass ("TestClosureGC$cl1").
getConstructor (hscs).newInstance (hsos);
new cld().loadClass ("TestClosureGC$cl1").
getConstructor (hscs).newInstance (hsos);
}
for (int i = 1; i <= 5; i++) {
/* System.out.println ("Will run GC and finalization " + i); */
System.gc ();
Thread.sleep (100);
System.runFinalization ();
Thread.sleep (100);
if (hs.isEmpty ())
continue;
java.util.Iterator it = hs.iterator ();
while (it.hasNext ()) {
Object obj = it.next();
/* System.out.println (objId (obj) + " in ht, removing"); */
it.remove ();
}
}
System.out.println ("ok");
}
}
|