2010-04-07 75 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

相關問題