mirror of
https://github.com/corda/corda.git
synced 2025-01-15 01:10:33 +00:00
finish java/lang/ref/* support; add wrapper classes for primitives
This commit is contained in:
parent
faf9b63798
commit
de9213ce30
13
classpath/java/lang/Boolean.java
Normal file
13
classpath/java/lang/Boolean.java
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
package java.lang;
|
||||||
|
|
||||||
|
public final class Boolean {
|
||||||
|
private final boolean value;
|
||||||
|
|
||||||
|
public Boolean(boolean value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean booleanValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
13
classpath/java/lang/Byte.java
Normal file
13
classpath/java/lang/Byte.java
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
package java.lang;
|
||||||
|
|
||||||
|
public final class Byte {
|
||||||
|
private final byte value;
|
||||||
|
|
||||||
|
public Byte(byte value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte byteValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
13
classpath/java/lang/Character.java
Normal file
13
classpath/java/lang/Character.java
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
package java.lang;
|
||||||
|
|
||||||
|
public final class Character {
|
||||||
|
private final char value;
|
||||||
|
|
||||||
|
public Character(char value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public char charValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
13
classpath/java/lang/Double.java
Normal file
13
classpath/java/lang/Double.java
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
package java.lang;
|
||||||
|
|
||||||
|
public final class Double {
|
||||||
|
private final double value;
|
||||||
|
|
||||||
|
public Double(double value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double doubleValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
13
classpath/java/lang/Float.java
Normal file
13
classpath/java/lang/Float.java
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
package java.lang;
|
||||||
|
|
||||||
|
public final class Float {
|
||||||
|
private final float value;
|
||||||
|
|
||||||
|
public Float(float value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float floatValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
13
classpath/java/lang/Integer.java
Normal file
13
classpath/java/lang/Integer.java
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
package java.lang;
|
||||||
|
|
||||||
|
public final class Integer {
|
||||||
|
private final int value;
|
||||||
|
|
||||||
|
public Integer(int value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int intValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
package java.lang;
|
package java.lang;
|
||||||
|
|
||||||
public class Long {
|
public final class Long {
|
||||||
private final long value;
|
private final long value;
|
||||||
|
|
||||||
public Long(long value) {
|
public Long(long value) {
|
||||||
|
13
classpath/java/lang/Short.java
Normal file
13
classpath/java/lang/Short.java
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
package java.lang;
|
||||||
|
|
||||||
|
public final class Short {
|
||||||
|
private final short value;
|
||||||
|
|
||||||
|
public Short(short value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public short shortValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
@ -10,14 +10,16 @@ public class StringBuilder {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public StringBuilder append(Object o) {
|
||||||
|
return append(o == null ? "null" : o.toString());
|
||||||
|
}
|
||||||
|
|
||||||
public StringBuilder append(int v) {
|
public StringBuilder append(int v) {
|
||||||
append(String.valueOf(v));
|
return append(String.valueOf(v));
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public StringBuilder append(long v) {
|
public StringBuilder append(long v) {
|
||||||
append(String.valueOf(v));
|
return append(String.valueOf(v));
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String toString() {
|
public String toString() {
|
||||||
|
@ -15,6 +15,8 @@ public abstract class System {
|
|||||||
|
|
||||||
public static native String getProperty(String name);
|
public static native String getProperty(String name);
|
||||||
|
|
||||||
|
public static native void gc();
|
||||||
|
|
||||||
public static class Output {
|
public static class Output {
|
||||||
public synchronized native void print(String s);
|
public synchronized native void print(String s);
|
||||||
|
|
||||||
|
5
classpath/java/lang/Void.java
Normal file
5
classpath/java/lang/Void.java
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
package java.lang;
|
||||||
|
|
||||||
|
public final class Void {
|
||||||
|
|
||||||
|
}
|
@ -4,7 +4,7 @@ public abstract class Reference<T> {
|
|||||||
private T target;
|
private T target;
|
||||||
private ReferenceQueue<? super T> queue;
|
private ReferenceQueue<? super T> queue;
|
||||||
private Object vmNext;
|
private Object vmNext;
|
||||||
Reference<? extends T> next;
|
Reference next;
|
||||||
|
|
||||||
protected Reference(T target, ReferenceQueue<? super T> queue) {
|
protected Reference(T target, ReferenceQueue<? super T> queue) {
|
||||||
this.target = target;
|
this.target = target;
|
||||||
@ -16,7 +16,7 @@ public abstract class Reference<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void clear() {
|
public void clear() {
|
||||||
target = 0;
|
target = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isEnqueued() {
|
public boolean isEnqueued() {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package java.lang.ref;
|
package java.lang.ref;
|
||||||
|
|
||||||
public abstract class ReferenceQueue<T> {
|
public class ReferenceQueue<T> {
|
||||||
private Reference<? extends T> front;
|
private Reference<? extends T> front;
|
||||||
private Reference<? extends T> rear;
|
private Reference<? extends T> rear;
|
||||||
|
|
||||||
|
2
makefile
2
makefile
@ -16,7 +16,7 @@ src = src
|
|||||||
classpath = classpath
|
classpath = classpath
|
||||||
test = test
|
test = test
|
||||||
|
|
||||||
input = $(cls)/Exceptions.class
|
input = $(cls)/References.class
|
||||||
|
|
||||||
cxx = g++
|
cxx = g++
|
||||||
cc = gcc
|
cc = gcc
|
||||||
|
@ -106,6 +106,14 @@ arraycopy(Thread* t, jobject src, jint srcOffset, jobject dst, jint dstOffset,
|
|||||||
t->exception = makeArrayStoreException(t);
|
t->exception = makeArrayStoreException(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gc(Thread* t)
|
||||||
|
{
|
||||||
|
ENTER(t, Thread::ExclusiveState);
|
||||||
|
|
||||||
|
collect(t, Heap::MajorCollection);
|
||||||
|
}
|
||||||
|
|
||||||
jobject
|
jobject
|
||||||
trace(Thread* t, jint skipCount)
|
trace(Thread* t, jint skipCount)
|
||||||
{
|
{
|
||||||
@ -217,6 +225,8 @@ populate(Thread* t, object map)
|
|||||||
reinterpret_cast<void*>(arraycopy) },
|
reinterpret_cast<void*>(arraycopy) },
|
||||||
{ "Java_java_lang_System_loadLibrary",
|
{ "Java_java_lang_System_loadLibrary",
|
||||||
reinterpret_cast<void*>(loadLibrary) },
|
reinterpret_cast<void*>(loadLibrary) },
|
||||||
|
{ "Java_java_lang_System_gc",
|
||||||
|
reinterpret_cast<void*>(gc) },
|
||||||
|
|
||||||
{ "Java_java_lang_Thread_start",
|
{ "Java_java_lang_Thread_start",
|
||||||
reinterpret_cast<void*>(start) },
|
reinterpret_cast<void*>(start) },
|
||||||
|
@ -1438,7 +1438,9 @@ makeHeap(System* system)
|
|||||||
virtual Status status(void* p) {
|
virtual Status status(void* p) {
|
||||||
p = mask(p);
|
p = mask(p);
|
||||||
|
|
||||||
if (c.nextGen1.contains(p)) {
|
if (p == 0) {
|
||||||
|
return Null;
|
||||||
|
} else if (c.nextGen1.contains(p)) {
|
||||||
return Reachable;
|
return Reachable;
|
||||||
} else if (c.nextGen2.contains(p)
|
} else if (c.nextGen2.contains(p)
|
||||||
or (c.gen2.contains(p)
|
or (c.gen2.contains(p)
|
||||||
|
@ -13,6 +13,7 @@ class Heap {
|
|||||||
};
|
};
|
||||||
|
|
||||||
enum Status {
|
enum Status {
|
||||||
|
Null,
|
||||||
Reachable,
|
Reachable,
|
||||||
Unreachable,
|
Unreachable,
|
||||||
Tenured
|
Tenured
|
||||||
|
@ -142,7 +142,9 @@ referenceTargetUnreachable(Thread* t, object* p, Heap::Visitor* v)
|
|||||||
v->visit(p);
|
v->visit(p);
|
||||||
jreferenceTarget(t, *p) = 0;
|
jreferenceTarget(t, *p) = 0;
|
||||||
|
|
||||||
if (t->vm->heap->status(jreferenceQueue(t, *p)) != Heap::Unreachable) {
|
if (jreferenceQueue(t, *p)
|
||||||
|
and t->vm->heap->status(jreferenceQueue(t, *p)) != Heap::Unreachable)
|
||||||
|
{
|
||||||
// queue is reachable - add the reference
|
// queue is reachable - add the reference
|
||||||
|
|
||||||
v->visit(&jreferenceQueue(t, *p));
|
v->visit(&jreferenceQueue(t, *p));
|
||||||
@ -161,6 +163,17 @@ referenceTargetUnreachable(Thread* t, object* p, Heap::Visitor* v)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
referenceUnreachable(Thread* t, object* p, Heap::Visitor* v)
|
||||||
|
{
|
||||||
|
if (jreferenceQueue(t, *p)
|
||||||
|
and t->vm->heap->status(jreferenceQueue(t, *p)) != Heap::Unreachable)
|
||||||
|
{
|
||||||
|
// queue is reachable - add the reference
|
||||||
|
referenceTargetUnreachable(t, p, v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
referenceTargetReachable(Thread* t, object* p, Heap::Visitor* v)
|
referenceTargetReachable(Thread* t, object* p, Heap::Visitor* v)
|
||||||
{
|
{
|
||||||
@ -222,12 +235,12 @@ postVisit(Thread* t, Heap::Visitor* v)
|
|||||||
|
|
||||||
for (object* p = &(m->weakReferences); *p;) {
|
for (object* p = &(m->weakReferences); *p;) {
|
||||||
if (m->heap->status(*p) == Heap::Unreachable) {
|
if (m->heap->status(*p) == Heap::Unreachable) {
|
||||||
// reference is unreachable - remove it from the list
|
// reference is unreachable
|
||||||
|
|
||||||
|
referenceUnreachable(t, p, v);
|
||||||
*p = jreferenceNext(t, *p);
|
*p = jreferenceNext(t, *p);
|
||||||
} else if (m->heap->status(jreferenceTarget(t, *p)) == Heap::Unreachable) {
|
} else if (m->heap->status(jreferenceTarget(t, *p)) == Heap::Unreachable) {
|
||||||
// target is unreachable - clear the reference, remove it from
|
// target is unreachable
|
||||||
// the list, and enqueue it if it has a live reference queue
|
|
||||||
|
|
||||||
referenceTargetUnreachable(t, p, v);
|
referenceTargetUnreachable(t, p, v);
|
||||||
*p = jreferenceNext(t, *p);
|
*p = jreferenceNext(t, *p);
|
||||||
@ -279,19 +292,19 @@ postVisit(Thread* t, Heap::Visitor* v)
|
|||||||
|
|
||||||
for (object* p = &(m->tenuredWeakReferences); *p;) {
|
for (object* p = &(m->tenuredWeakReferences); *p;) {
|
||||||
if (m->heap->status(*p) == Heap::Unreachable) {
|
if (m->heap->status(*p) == Heap::Unreachable) {
|
||||||
// reference is unreachable - remove it from the list
|
// reference is unreachable
|
||||||
|
|
||||||
|
referenceUnreachable(t, p, v);
|
||||||
*p = jreferenceNext(t, *p);
|
*p = jreferenceNext(t, *p);
|
||||||
} else if (m->heap->status(jreferenceTarget(t, *p))
|
} else if (m->heap->status(jreferenceTarget(t, *p))
|
||||||
== Heap::Unreachable)
|
== Heap::Unreachable)
|
||||||
{
|
{
|
||||||
// target is unreachable - clear the reference, remove it from
|
// target is unreachable
|
||||||
// the list, and enqueue it if it has a live reference queue
|
|
||||||
|
|
||||||
referenceTargetUnreachable(t, p, v);
|
referenceTargetUnreachable(t, p, v);
|
||||||
*p = jreferenceNext(t, *p);
|
*p = jreferenceNext(t, *p);
|
||||||
} else {
|
} else {
|
||||||
// target is reachable
|
// both reference and target are reachable
|
||||||
|
|
||||||
referenceTargetReachable(t, p, v);
|
referenceTargetReachable(t, p, v);
|
||||||
p = &jreferenceNext(t, *p);
|
p = &jreferenceNext(t, *p);
|
||||||
@ -1106,7 +1119,9 @@ updateBootstrapClass(Thread* t, object bootstrapClass, object class_)
|
|||||||
// verify that the classes have the same layout
|
// verify that the classes have the same layout
|
||||||
expect(t, classSuper(t, bootstrapClass) == classSuper(t, class_));
|
expect(t, classSuper(t, bootstrapClass) == classSuper(t, class_));
|
||||||
expect(t, classFixedSize(t, bootstrapClass) == classFixedSize(t, class_));
|
expect(t, classFixedSize(t, bootstrapClass) == classFixedSize(t, class_));
|
||||||
expect(t, (classObjectMask(t, bootstrapClass) == 0
|
expect(t,
|
||||||
|
(classVmFlags(t, bootstrapClass) & ReferenceFlag)
|
||||||
|
or (classObjectMask(t, bootstrapClass) == 0
|
||||||
and classObjectMask(t, class_) == 0)
|
and classObjectMask(t, class_) == 0)
|
||||||
or intArrayEqual(t, classObjectMask(t, bootstrapClass),
|
or intArrayEqual(t, classObjectMask(t, bootstrapClass),
|
||||||
classObjectMask(t, class_)));
|
classObjectMask(t, class_)));
|
||||||
@ -1243,7 +1258,7 @@ Machine::Machine(System* system, Heap* heap, ClassFinder* classFinder):
|
|||||||
stateLock(0),
|
stateLock(0),
|
||||||
heapLock(0),
|
heapLock(0),
|
||||||
classLock(0),
|
classLock(0),
|
||||||
finalizerLock(0),
|
referenceLock(0),
|
||||||
libraries(0),
|
libraries(0),
|
||||||
classMap(0),
|
classMap(0),
|
||||||
bootstrapClassMap(0),
|
bootstrapClassMap(0),
|
||||||
@ -1262,7 +1277,7 @@ Machine::Machine(System* system, Heap* heap, ClassFinder* classFinder):
|
|||||||
if (not system->success(system->make(&stateLock)) or
|
if (not system->success(system->make(&stateLock)) or
|
||||||
not system->success(system->make(&heapLock)) or
|
not system->success(system->make(&heapLock)) or
|
||||||
not system->success(system->make(&classLock)) or
|
not system->success(system->make(&classLock)) or
|
||||||
not system->success(system->make(&finalizerLock)))
|
not system->success(system->make(&referenceLock)))
|
||||||
{
|
{
|
||||||
system->abort();
|
system->abort();
|
||||||
}
|
}
|
||||||
@ -1274,7 +1289,7 @@ Machine::dispose()
|
|||||||
stateLock->dispose();
|
stateLock->dispose();
|
||||||
heapLock->dispose();
|
heapLock->dispose();
|
||||||
classLock->dispose();
|
classLock->dispose();
|
||||||
finalizerLock->dispose();
|
referenceLock->dispose();
|
||||||
|
|
||||||
if (libraries) {
|
if (libraries) {
|
||||||
libraries->dispose();
|
libraries->dispose();
|
||||||
@ -1339,6 +1354,13 @@ Thread::Thread(Machine* m, Allocator* allocator, object javaThread,
|
|||||||
|
|
||||||
m->unsafe = false;
|
m->unsafe = false;
|
||||||
|
|
||||||
|
classVmFlags(t, arrayBody(t, m->types, Machine::JreferenceType))
|
||||||
|
|= ReferenceFlag;
|
||||||
|
classVmFlags(t, arrayBody(t, m->types, Machine::WeakReferenceType))
|
||||||
|
|= ReferenceFlag | WeakReferenceFlag;
|
||||||
|
classVmFlags(t, arrayBody(t, m->types, Machine::PhantomReferenceType))
|
||||||
|
|= ReferenceFlag | WeakReferenceFlag;
|
||||||
|
|
||||||
m->bootstrapClassMap = makeHashMap(this, NormalMap, 0, 0);
|
m->bootstrapClassMap = makeHashMap(this, NormalMap, 0, 0);
|
||||||
|
|
||||||
#include "type-java-initializations.cpp"
|
#include "type-java-initializations.cpp"
|
||||||
@ -2090,7 +2112,7 @@ addFinalizer(Thread* t, object target, void (*finalize)(Thread*, object))
|
|||||||
{
|
{
|
||||||
PROTECT(t, target);
|
PROTECT(t, target);
|
||||||
|
|
||||||
ACQUIRE(t, t->vm->finalizerLock);
|
ACQUIRE(t, t->vm->referenceLock);
|
||||||
|
|
||||||
t->vm->finalizers = makeFinalizer
|
t->vm->finalizers = makeFinalizer
|
||||||
(t, 0, reinterpret_cast<void*>(finalize), t->vm->finalizers);
|
(t, 0, reinterpret_cast<void*>(finalize), t->vm->finalizers);
|
||||||
|
@ -61,6 +61,9 @@ enum MapType {
|
|||||||
const int NativeLine = -1;
|
const int NativeLine = -1;
|
||||||
const int UnknownLine = -2;
|
const int UnknownLine = -2;
|
||||||
|
|
||||||
|
const unsigned ReferenceFlag = 1 << 0;
|
||||||
|
const unsigned WeakReferenceFlag = 1 << 1;
|
||||||
|
|
||||||
class Thread;
|
class Thread;
|
||||||
|
|
||||||
typedef Thread JNIEnv;
|
typedef Thread JNIEnv;
|
||||||
@ -1106,7 +1109,7 @@ class Machine {
|
|||||||
System::Monitor* stateLock;
|
System::Monitor* stateLock;
|
||||||
System::Monitor* heapLock;
|
System::Monitor* heapLock;
|
||||||
System::Monitor* classLock;
|
System::Monitor* classLock;
|
||||||
System::Monitor* finalizerLock;
|
System::Monitor* referenceLock;
|
||||||
System::Library* libraries;
|
System::Library* libraries;
|
||||||
object classMap;
|
object classMap;
|
||||||
object bootstrapClassMap;
|
object bootstrapClassMap;
|
||||||
|
24
src/run.cpp
24
src/run.cpp
@ -76,6 +76,18 @@ popFrame(Thread* t)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
registerWeakReference(Thread* t, object r)
|
||||||
|
{
|
||||||
|
PROTECT(t, r);
|
||||||
|
|
||||||
|
ACQUIRE(t, t->vm->referenceLock);
|
||||||
|
|
||||||
|
// jreferenceNext(t, r)
|
||||||
|
cast<object>(r, 3 * BytesPerWord) = t->vm->weakReferences;
|
||||||
|
t->vm->weakReferences = r;
|
||||||
|
}
|
||||||
|
|
||||||
inline object
|
inline object
|
||||||
make(Thread* t, object class_)
|
make(Thread* t, object class_)
|
||||||
{
|
{
|
||||||
@ -86,6 +98,10 @@ make(Thread* t, object class_)
|
|||||||
memset(static_cast<object*>(instance) + 1, 0,
|
memset(static_cast<object*>(instance) + 1, 0,
|
||||||
sizeInBytes - sizeof(object));
|
sizeInBytes - sizeof(object));
|
||||||
|
|
||||||
|
if (UNLIKELY(classVmFlags(t, class_) & WeakReferenceFlag)) {
|
||||||
|
registerWeakReference(t, instance);
|
||||||
|
}
|
||||||
|
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1085,8 +1101,8 @@ run(Thread* t)
|
|||||||
uint8_t offset1 = codeBody(t, code, ip++);
|
uint8_t offset1 = codeBody(t, code, ip++);
|
||||||
uint8_t offset2 = codeBody(t, code, ip++);
|
uint8_t offset2 = codeBody(t, code, ip++);
|
||||||
|
|
||||||
int32_t b = popInt(t);
|
object b = popObject(t);
|
||||||
int32_t a = popInt(t);
|
object a = popObject(t);
|
||||||
|
|
||||||
if (a == b) {
|
if (a == b) {
|
||||||
ip = (ip - 3) + static_cast<int16_t>(((offset1 << 8) | offset2));
|
ip = (ip - 3) + static_cast<int16_t>(((offset1 << 8) | offset2));
|
||||||
@ -1097,8 +1113,8 @@ run(Thread* t)
|
|||||||
uint8_t offset1 = codeBody(t, code, ip++);
|
uint8_t offset1 = codeBody(t, code, ip++);
|
||||||
uint8_t offset2 = codeBody(t, code, ip++);
|
uint8_t offset2 = codeBody(t, code, ip++);
|
||||||
|
|
||||||
int32_t b = popInt(t);
|
object b = popObject(t);
|
||||||
int32_t a = popInt(t);
|
object a = popObject(t);
|
||||||
|
|
||||||
if (a != b) {
|
if (a != b) {
|
||||||
ip = (ip - 3) + static_cast<int16_t>(((offset1 << 8) | offset2));
|
ip = (ip - 3) + static_cast<int16_t>(((offset1 << 8) | offset2));
|
||||||
|
36
test/References.java
Normal file
36
test/References.java
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
import java.lang.ref.ReferenceQueue;
|
||||||
|
import java.lang.ref.Reference;
|
||||||
|
import java.lang.ref.WeakReference;
|
||||||
|
import java.lang.ref.PhantomReference;
|
||||||
|
|
||||||
|
public class References {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
Object a = new Object();
|
||||||
|
Object b = new Object();
|
||||||
|
Object c = new Object();
|
||||||
|
Object d = new Object();
|
||||||
|
|
||||||
|
ReferenceQueue q = new ReferenceQueue();
|
||||||
|
|
||||||
|
Reference ar = new WeakReference(a);
|
||||||
|
Reference br = new WeakReference(b, q);
|
||||||
|
Reference cr = new WeakReference(c, q);
|
||||||
|
Reference dr = new PhantomReference(d, q);
|
||||||
|
|
||||||
|
a = b = c = d = cr = null;
|
||||||
|
|
||||||
|
System.out.println("a: " + ar.get());
|
||||||
|
System.out.println("b: " + br.get());
|
||||||
|
System.out.println("d: " + dr.get());
|
||||||
|
|
||||||
|
System.gc();
|
||||||
|
|
||||||
|
System.out.println("a: " + ar.get());
|
||||||
|
System.out.println("b: " + br.get());
|
||||||
|
System.out.println("d: " + dr.get());
|
||||||
|
|
||||||
|
for (Reference r = q.poll(); r != null; r = q.poll()) {
|
||||||
|
System.out.println("polled: " + r.get());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user