Name: nt126004 Date: 03/04/2002
FULL PRODUCT VERSION :
java version "1.4.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0-b92)
Java HotSpot(TM) Client VM (build 1.4.0-b92, mixed mode)
FULL OPERATING SYSTEM VERSION :
Microsoft Windows 2000 [Version 5.00.2195]
A DESCRIPTION OF THE PROBLEM :
XMLEncoder looses custom PersistenceDelegate after
intensive memory allocation. It works as expected under
1.4.0beta3 but fails on 1.4.0RC1.
In the provided test program, I create new 1MB array in
loop and check whether or not getPersistenceDelegate()
returns the same object, i've put by
setPersistenceDelegate() earlier.
Test output shows, that:
1. on 1.4.0RC1 check fails after third allocation. (because
JVM starts by default with 2M memory pool)
2. on 1.4.0Beta3 check is OK on 10 allocations.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1.Compile provided class.
2.Run test:
java persistence_test.Test
EXPECTED VERSUS ACTUAL BEHAVIOR :
Output on 1.4.0RC1:
Before memory allocation: OK
0 OK
1 OK
2 Different: persistence_test.Test$1 :
java.beans.DefaultPersistenceDelegate
Test finished
Output on 1.4.0beta3:
Before memory allocation: OK
0 OK
1 OK
2 OK
3 OK
4 OK
5 OK
6 OK
7 OK
8 OK
9 OK
Test finished
Note:
The actual results would depend on how many memory JVM
allocated on startup on your system...
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
package persistence_test;
import java.beans.*;
import java.io.*;
public class PersistenceTest {
public static void main(String[] args){
final int ARRAYSIZE = 1000000;
final int BUFERLENGTH = 10;
try{
XMLEncoder encoder = new XMLEncoder(new BufferedOutputStream(new
ByteArrayOutputStream()));
PersistenceDelegate pd = new DefaultPersistenceDelegate(){
protected Expression instantiate(Object oldInstance, Encoder
out) {
return super.instantiate(oldInstance, out);
}
protected void initialize(Class type, Object oldInstance,
Object newInstance, Encoder out) {
super.initialize(type, oldInstance, newInstance, out);
}
};
encoder.setPersistenceDelegate(Test.class, pd);
Object[] bufArray = new Object[BUFERLENGTH];
System.out.print("Before memory allocation: ");
checkClasses(pd, encoder.getPersistenceDelegate(Test.class));
for(int i=0; i < BUFERLENGTH; i++){
bufArray[i] = new byte[ARRAYSIZE];
System.out.print(i + " ");
if (checkClasses(pd, encoder.getPersistenceDelegate
(Test.class))) break;
}
encoder.close();
System.out.println("Test finished");
}catch(Exception ex){
ex.printStackTrace();
}
}
public static boolean checkClasses(PersistenceDelegate pd1,
PersistenceDelegate pd2){
if (pd1 == pd2)
System.out.println("OK");
else{
System.out.println("Different: " + pd1.getClass().getName()
+ " : " + pd2.getClass().getName());
}
return pd1 != pd2;
}
}
---------- END SOURCE ----------
CUSTOMER WORKAROUND :
The possible ugly work around is increasing JVM startup
memory amount with -Xms key.
(Review ID: 139123)
======================================================================