2010-04-07 40 views
2

我有一个在Java中的图形结构(“图形”在“边缘和节点”),我试图序列化它。不过,尽管显着增加了JVM堆栈的大小,但我却得到了“StackOverflowException”。我做了一些Google搜索,显然这是一个众所周知的Java序列化限制:它不适用于深层嵌套的对象图,如长链表 - 它为链中的每个链接使用堆栈记录,不要做任何聪明的事情,比如广度优先遍历,因此你很快就会出现堆栈溢出。如何在没有得到StackOverflowException的情况下在Java中序列化图形?

推荐的解决方案是通过覆盖readObject()和writeObject()来自定义序列化代码,但是这对我来说似乎有点复杂。 (这可能也可能不相关,但我在图的每个边上存储了一堆字段,所以我有一个类JuNode其中包含一个成员ArrayList<JuEdge> links;,即有2个类涉及,而不是简单的从一个节点到另一个节点的对象引用对于问题的目的应该没有关系)。

我的问题有三个:
(a)为什么Java的实现者不纠正这种限制或者他们已经在使用它? (我不敢相信我是第一个想用java编写一个图表的人)
(b)有没有更好的方法?是否有一些替代默认序列化类的替代方法能够以更聪明的方式实现? (c)如果我最好的选择是用低级代码弄脏我的双手,有人有一个图形序列化java源代码的例子,可以用来学习如何做到这一点吗?

+2

难道是你的图中的一个循环会引发一个不断增长的调用堆栈,试图序列化A - > A.links - > B - > B.links - > A?在这种情况下,我建议先串行化一堆节点,接下来是一堆边缘(使用某种类型的节点ID)。 – helios 2010-04-07 07:58:24

+0

或者编写一个“remember-already-serialized-objects”ObjectOutputStream和ObjectInputStream,它知道它是否在序列化之前序列化一个对象(在序列化时持有一组引用),并且不要将它写两次(以及编写引用... ) – helios 2010-04-07 08:00:22

+2

Helios,序列化机制已经处理对象图中的循环并且不止一次地防止同一对象的序列化。 – Adamski 2010-04-07 09:02:26

回答

0

这里有一些奇怪的东西。 你的意思是你在内存中有一个obejct图,调用序列化代码的事实会产生StackOverflowException?如果是这样,这意味着您的图涉及很多延迟加载元素,而这些元素不会传播到序列化。

换句话说,我很清楚你的应用程序已经被优化了,因为它的尺寸很大。但是,不幸的是,您没有在序列化代码中利用这些优化,而是更愿意直接序列化您的根对象,其中涉及加载所有子代并引发异常。

我真的强烈建议你,而不是实现Externalizable接口,这实际上是比实现readObject/writeObject同样的事情,使用现有的优化,但在一个更加面向对象的方式。另外,为了让您自己能够访问您的对象写入的数据,请考虑使用XMLEncoder/XMLDecoder,它的工作方式与序列化相似,但产生“可读”的XML。

+0

考虑到序列化是什么,我不确定'Externalizable'是多么OO。 'XMLEncode'我会远离。 – 2010-04-07 10:56:04

+0

方法的readObject/writeObject对在任何接口之外定义。事实上,有一个“隐式”接口,这些接口定义了这些方法,但它没有定义。与明确定义readExternal/writeExternal契约的Externalizable接口相反,确保实现它的人必须编写所需的方法,这些方法与readObject/writeObject完全相同,但是以明确的方式进行。 – Riduidel 2010-04-07 13:03:45

+0

你能解释一下为什么你会远离XMLEncoder吗? – Riduidel 2010-04-07 13:04:06

1

尽管可以对其进行优化,但Java序列化规范基本上是递归的。您可以并且经常会提供writeObject(和readObject)方法。在执行时,必须写入引用的对象。即使广度优先遍历是可能的,它也无济于事。

Sun/Oracle JDK是开源的,并且愿意捐款。

java.util.LinkedList将有一个如何有效地连续化链表的例子。

+0

为什么不能广度优先遍历帮助?它会解决堆栈溢出问题,这是我唯一的问题。你的意思是改为“根据规范宽度优先是不可能的”? – 2010-04-08 00:17:57

+1

该问题基本上是递归的。如果您将递归位取出并保持状态离开程序状态,则遍历顺序无关紧要。 – 2010-04-08 01:26:20

相关问题