United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
JDK-4152790 : StackOverFlowError serializing/deserializing a large graph of objects.

Details
Type:
Enhancement
Submit Date:
1998-06-26
Status:
Open
Updated Date:
2014-08-28
Project Name:
JDK
Resolved Date:
Component:
core-libs
OS:
solaris_2.5,windows_nt,generic,windows_xp,windows_2000
Sub-Component:
java.io:serialization
CPU:
x86,generic
Priority:
P4
Resolution:
Unresolved
Affected Versions:
1.0,1.1.6,1.1.7,1.3.0,1.3.0_01,1.4.2,5.0u9
Targeted Versions:

Related Reports
Duplicate:
Duplicate:
Duplicate:
Duplicate:

Sub Tasks

Description
Summary: Serializing recursively calls writeObject, resulting in 
         java.lang.StackOverFlowError being thrown when the
         object graph is deeply nested (example: long link list).
         Since serialiation is being performed on a server
         that spawns a thread for each client, it is not possible
	 to up the stack size to workaround this capacity limitation for
	 each thread.

Customer mail message:

Apparently an object O is serialized in a "pre-order" walk of the
object graph rooted at O. Thus if O points to O', O' is
serialized first, and then O. JDK 1.1.6 and earlier versions seem
to implement this by using the stack to do the recursion.

This has the hugely unfortunate property of limiting the size of
the graphs that can be serialized. Trying to serialize a linked
list of 1000 elements blew my stack on an WinNT! In essence, one
cannot serialize an object graph which can grow arbitrarily
large.

I am led to believe that it is not possible in Java to grow the
stack size arbitrarily in a data-dependent manner from inside the
JVM. Why not do this recursion in the heap then?

Or, perhaps even better, why not do the serialization in a
"post-order" walk (generating a handle on O', stashing that away
in a table, finishing the serialization of O (using the handle
for all future accesses to O') and then coming back to serialize
all the objects in the table that have not yet been serialized)?

Are any patches available for this functionality? I can try to
fake it in my application, but the problem is that I do not
control the code being loaded into the JVM --- so I cannot
control the {write/read}Object methods for all classes.


                                    

Comments
WORK AROUND

The recommended work-around is to define custom writeObject and readObject
methods which transmit the nested/linked data structures as a flat sequence of
objects.  One example of this is the writeObject/readObject methods of
java.util.LinkedList.  The following post to the rmi-users mailing list
explains another (similar) example:

http://swjscmail1.java.sun.com/cgi-bin/wa?A2=ind9909&L=rmi-users&F=&S=&P=34494
                                     
2004-10-02
EVALUATION

The cause of this problem is well-known. It looked like a
practical work-around existed of upping the native stack size.
However, this workaround is not sufficent when many threads
all all trying to serialize. 

More thought should be given to use heap space over stack space
to serialize a graph of objects. This is too risky a change
to make for JDK 1.2, but needs to be considered in the future.

joseph.fialli@East 1998-06-26

Will fix for merlin. The new mechanism wouuld switch from a recursive algorithm 
to an iterative one at a predetermined recursion depth. See comments.

naveen.sanjeeva@eng 2000-06-15

Not enough time/resources to fix this for merlin.  Will leave open for
consideration in a future release.

michael.warres@east 2000-12-27
                                     
2000-06-15



Hardware and Software, Engineered to Work Together