SoftReference & WeakReference: time of life

Well, I found some free time to write few articles. This one is about the SoftReference class from Java library.
SoftReference will help you to get the best variant between using memory and performance. Soft reference means that the value wrapped in soft reference will be garbage collected only and only if there are no free memory.
More about this. First I set -verbose:gc parameter for Java machine. If this parameter is set than GC logs will be output to the console. Also was set parameter -Xmx32m. The simple code:

void test() {
Reference<List> listRef = new SoftReference<List>(
Arrays.asList("1", "2", "3", "4", "5"));

List list = new LinkedList();
for (int i = 1; i <= 5; i++) {
list.add(new Object());

if (i == 5) {
if (listRef.get() == null) {
break;
}
i = 1;
}
}
}

Here the soft reference to the long string was created. The loop adds the references to the object to the linked list. Sometimes it checks whether the soft reference to the list of strings is not gc'ed; if it is than loop is breaked. Here is the output of GC:

[GC 896K->708K(5056K), 0.0059887 secs]
[GC 1604K->1603K(5056K), 0.0064902 secs]
[GC 2499K->2498K(5056K), 0.0064698 secs]
[GC 3394K->3393K(5056K), 0.0062198 secs]
[GC 4289K->4287K(5184K), 0.0061248 secs]
[Full GC 4287K->4287K(5184K), 0.0378679 secs]
[GC 5120K->5119K(8000K), 0.0141557 secs]
[GC 6015K->6014K(8000K), 0.0069241 secs]
[GC 6910K->6908K(8000K), 0.0064464 secs]
[GC 7804K->7804K(8768K), 0.0061396 secs]
[Full GC 7804K->7804K(8768K), 0.0595140 secs]

We may see that more than one Full GC were run before the soft reference was cleaned up.
The same test for the WeakReference (change new SoftReference(...) into new WeakReference(...)) prints next output:

[GC 896K->707K(5056K), 0.0063061 secs]

So, weak reference is cleaned up after the next first GC runs.
These tests were made on Java 1.6.0_10.
The outputs for Java 1.5.0_07 are respectively

[GC 512K->387K(1984K), 0.0047419 secs]
[GC 899K->898K(1984K), 0.0046456 secs]
[GC 1410K->1409K(1984K), 0.0048894 secs]
[GC 1921K->1920K(2496K), 0.0046743 secs]
[Full GC 1920K->1920K(2496K), 0.0203305 secs]
[GC 2431K->2430K(3776K), 0.0103943 secs]
[GC 2942K->2941K(3776K), 0.0048556 secs]
[GC 3453K->3452K(4032K), 0.0047855 secs]
[Full GC 3452K->3452K(4032K), 0.0340532 secs]
[GC 3964K->3963K(6332K), 0.0044411 secs]
[GC 4475K->4474K(6332K), 0.0049126 secs]
[GC 4986K->4985K(6332K), 0.0046232 secs]
[GC 5497K->5496K(6332K), 0.0045682 secs]
[GC 6008K->6007K(6588K), 0.0047892 secs]
[Full GC 6007K->6007K(6588K), 0.0523812 secs]
[GC 6775K->6774K(10848K), 0.0061404 secs]
[GC 7542K->7540K(10848K), 0.0065743 secs]
[GC 8308K->8307K(10848K), 0.0067296 secs]
[GC 9075K->9074K(10848K), 0.0066386 secs]
[GC 9842K->9841K(10848K), 0.0066439 secs]
[GC 10609K->10608K(11488K), 0.0066955 secs]
[Full GC 10608K->10606K(11488K), 0.1112694 secs]

and

[GC 512K->387K(1984K), 0.0049869 secs]


Since, these results show that Java 6 works with memory better than Java 5 and cleans up the soft reference faster than it is in Java 5.

No comments: