SoftReferences and WeakReferences
clebert.suconic Mar 10, 2006 1:58 PMAnyone know in detail when a SoftReference is supposed to be cleared?
I'm creating a testcase, using jbossProfiler interface, to validate classUnloading in a javaSerialization, and the class is not being unloaded when I expect.
the reason why I'm testing JavaSerialization, is because I was having problems with SoftReferences on JBossSerialization, and I wanted to validate the behavior of these references on a regular JavaSerialization.
There are still references on a SoftCache somewhere:
This is the testcase...
public void testJavaSerialization() throws Exception
{
JVMTIInterface jvmtiInterface = new JVMTIInterface();
try
{
serializeJava(jvmtiInterface);
ClassMetamodelFactory.clear();
ArrayList newList = new ArrayList();
// forcing a OutOfMemoryError, just to see if the SoftCache is cleared as stated on SoftCache javadoc
try
{
int count=0;
while (true)
{
newList.add("sdflkjsdlf jsflkja dflaj df;lkjas dfokjas dfkajs dfakjsdf sdfklj sdflkjs dflksjd flskjdf slkdjf slkdfj sldkfj sldfkj sfdlkj oadsjf oaidjf aosidjf aosidjf aosdijf aoidsfj aosidjf " + (count++));
}
}
catch (OutOfMemoryError e)
{
System.out.println("Clearing newList");
jvmtiInterface.forceGC();
newList.clear();
jvmtiInterface.forceGC();
}
Class clazz = jvmtiInterface.getClassByName(CLASS_NAME);
if (clazz!=null)
{
Object obj = clazz;
Object[] referenceHolders = printReferences(jvmtiInterface, obj);
// You can use JBossProfiler to analyze this snapshot
jvmtiInterface.heapSnapshot("./memory-tst","mem");
}
assertNull("Class org.jboss.serial.memory.SomePojo should been unloaded already",clazz);
}
catch (Exception e)
{
e.printStackTrace();
Class clazz = jvmtiInterface.getClassByName(CLASS_NAME);
if (clazz!=null)
{
Object obj = clazz;
Object[] referenceHolders = printReferences(jvmtiInterface, obj);
// You can use JBossProfiler to analyze this snapshot
jvmtiInterface.heapSnapshot("./memory-ex2","mem");
}
System.out.println("Class org.jboss.serial.memory.SomePojo should been unloaded already" + clazz);
throw e;
}
}
And this is the serializeJava method:
Notice that if I comment out writeObject, the class is cleared from the Heap
private void serializeJava(JVMTIInterface jvmtiInterface) throws Exception {
Thread newThread = new Thread()
{
public void run() {
try
{
URLClassLoader loader = newClassLoader();
Class testClass = loader.loadClass(CLASS_NAME);
Object someInstance = testClass.newInstance();
ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
ObjectOutputStream objOut = new ObjectOutputStream(byteOut);
objOut.writeObject(someInstance);
objOut.flush();
loader=null;
testClass=null;
someInstance=null;
objOut=null;
}
catch (Exception e)
{
e.printStackTrace();
}
}
};
newThread.start();
newThread.join();
}
I'm getting this output, for objects holding references:
References for class org.jboss.serial.memory.test.SomePojo
Reference[0]=[Ljava.lang.Object;
Reference[1]=java.util.HashMap$Entry