如何在不使用StackOverflowException的情况下在Java中序列化图形?

时间:2010-04-07 07:08:11

标签: java serialization graph

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

推荐的解决方案是通过重写readObject()和writeObject()来自定义序列化代码,但这对我来说似乎有点复杂。

(它可能相关,也可能不相关,但我在图中的每个边上存储了一堆字段,所以我有一个包含成员JuNode的类ArrayList<JuEdge> links;,即有涉及2个类,而不是从一个节点到另一个节点的简单对象引用。对于问题的目的而言无关紧要。)

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

2 个答案:

答案 0 :(得分:1)

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

Sun / Oracle JDK是开源的,可以参与贡献。

java.util.LinkedList将举例说明如何有效地序列化链表。

答案 1 :(得分:0)

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

换句话说,我很清楚您的应用程序已经因其庞大的尺寸而得到优化。但是,不幸的是,你没有利用序列化代码中的那些优化,而是更喜欢直接序列化你的根对象,这包括加载所有的孩子并激活那个异常。

我强烈建议您使用现有的优化,而不是实现Externalizable接口,这实际上与实现readObject / writeObject相同,但更多的是OO方式。

另外,为了让您自己可以访问对象编写的数据,请考虑使用XMLEncoder / XMLDecoder,它与序列化一样,但会生成“可读”的XML。