However, garbage collection on string literals is far more interesting. See the unit tests.
import static org.junit.Assert.*;
import java.lang.ref.WeakReference;
import org.junit.Test;
public class ReferenceTest
{
@Test
public void testWeakReference()
{
Object reference = new Object();
WeakReference<Object> weakRef =
new WeakReference<Object>(reference);
assertNotNull(reference);
reference = null;
// reference will not be null
// without garbage collection here
System.gc();
assertNull(weakRef.get());
}
@Test
public void testWeakStringReference()
{
String reference = new String();
WeakReference<String> weakRef =
new WeakReference<String>(reference);
assertNotNull(reference);
reference = null;
// reference will not be null
// without garbage collection here
System.gc();
assertNull(weakRef.get());
}
@Test
public void testWeakStringLiteralReference()
{
String reference = "my reference";
WeakReference<String> weakRef =
new WeakReference<String>(reference);
assertNotNull(reference);
reference = null;
// does not matter if garbage collection
// is here or not but lets do it anyway
System.gc();
// !!!
assertNotNull(weakRef.get());
}
}
All of these tests pass. Notice the last test, even after the string instance has been nulled the WeakReference still has a not null value. After a bit of googling I found that string literals are referenced from Javas 'String Literal Pool' which is a cache for string literals so is not eligible for garbage collection!