how does "SoftReference" and "WeakReference" work?

Hello, everybody!

I want to design a cache with "SoftReference"

the cache is just like:

int length = 1024;

Object[] cacheObjects =new Object[length+1];

cacheObjects[value.hashCode() & length] =new SoftReference(value);

I hope the "value" and soft reference are cleared by gc at some time before throwing "OutOfMemoryError" if there is no directly reference to the "value" object.

So I wrote a simple test:

privatestaticvoid softCache(){

int i = 400000;

List<String> list =new ArrayList<String>(i + 1);

String a ="....";// a huge string;

while (i-- > 0){

list.add(a + i);

}

Reference<Object> ref =new SoftReference<Object>(110);

try{

long[] b =newlong[20000000];

System.out.println(b[0]);

}catch (Exception e){

}finally{

System.out.println(ref.get());

}

System.out.println("OK");

}

The test result is:

theref and the110 object are not cleared before throw "OutOfMemoryError".

Why?

[2023 byte] By [lihy70a] at [2007-11-27 4:38:24]
# 1

Well, for a start the result of boxing 110 is a reference to a static Integer object - Integer has predefined instances for numbers up to 128, I believe. So there's a strong reference to it, and it can't be cleared. The ref variable won't be cleared, because it's a strong reference to a WeekReference object.

Your has table stuff is wrong (you need to use % length not & length, and allow for synonyms, i.e. different objects with the same hashCode), might as well stick to HashMap. You need a seperate key anyway to find the appropriate object in a cache.

You should also use a cleanup thread. Create a reference queue and attach the SoftReferences to it, then a cleanup thread deletes the entries from the hashtable when their references are cleared. The requires extending the SoftReference class to add the key information needed to find and clear the hash table entry.

malcolmmca at 2007-7-12 9:48:51 > top of Java-index,Java Essentials,Java Programming...
# 2

> Well, for a start the result of boxing 110 is a

> reference to a static Integer object - Integer has

> predefined instances for numbers up to 128, I

> believe. So there's a strong reference to it, and it

> can't be cleared. The ref variable won't be cleared,

> because it's a strong reference to a WeekReference

> object.

Yes, you are right. If I change 110 to 1000. it was cleared.

Thanks.

> Your has table stuff is wrong (you need to use %

> length not & length, and allow for synonyms, i.e.

> different objects with the same hashCode), might as

> well stick to HashMap. You need a seperate key anyway

> to find the appropriate object in a cache.

why '% length', not '& length'?

It 's allowed to cover by the object with same hashCode.

here the cache is for huge number object(may more than 10,000, 000).

It's more important to save space and improve speed if match probability > 90%. not nedd to find the appropriate object for each key.

> You should also use a cleanup thread. Create a

> reference queue and attach the SoftReferences to it,

> then a cleanup thread deletes the entries from the

> hashtable when their references are cleared. The

> requires extending the SoftReference class to add the

> key information needed to find and clear the hash

> table entry.

yes. thank your advice.

lihy70a at 2007-7-12 9:48:51 > top of Java-index,Java Essentials,Java Programming...
# 3

> why '% length', not '& length'?

To avoid collisions. When you binary-and (&) with 1024, a power of two, the result is either 1024 or 0. This means that only the two indices, 1024 and 0, will be used in your array. No other values can be obtained. You might as well use an array of length 2. This is why the remainder (%) is better usually.

If the length was 1023 or any other number of the form 2^n - 1, % and & would do the same thing.

Have you heard of WeakHashMap?

http://java.sun.com/j2se/1.4.2/docs/api/java/util/WeakHashMap.html

jsalonena at 2007-7-12 9:48:51 > top of Java-index,Java Essentials,Java Programming...
# 4
I see :-)thank you!
lihy70a at 2007-7-12 9:48:51 > top of Java-index,Java Essentials,Java Programming...
# 5

>

> If the length was 1023 or any other number of the

> form 2^n - 1, % and & would do the same thing.

>

No, only if the length was 2^n and you anded with 2^n - 1

> Have you heard of WeakHashMap?

WeakHashMap serves a competely different purpose because it's not the values in the WeakHashMap which are Weak, but the keys.

A WeakHashMap is a good way to assciate extra data with an object you can't get at to extend (e.g. a java.sql.Connection). I can't see you can use it for caching.

malcolmmca at 2007-7-12 9:48:51 > top of Java-index,Java Essentials,Java Programming...
# 6
> No, only if the length was 2^n and you anded with 2^n> - 1> Yes, you are right, the indices will reach 2^n-1 so the size of the array has to be 2^n.
jsalonena at 2007-7-12 9:48:51 > top of Java-index,Java Essentials,Java Programming...
# 7

Hello,

I got another problem.

If there is lot of object to cache, need to create a lot of SoftReference.

This will take a lot of time and space.

Is there any way make array having the features of SoftReference?

So not need to create a SoftReference for each array element.

that's to say, how to let one SoftReference refer to more than object

lihy70a at 2007-7-12 9:48:51 > top of Java-index,Java Essentials,Java Programming...
# 8

>

> Is there any way make array having the features of

> SoftReference?

> So not need to create a SoftReference for each array

> element.

> that's to say, how to let one SoftReference refer to

> more than object

Can't see it, because Reference objects are treated specially by the garbage collector, so there's no way you could write your own.

malcolmmca at 2007-7-12 9:48:51 > top of Java-index,Java Essentials,Java Programming...