我序列化对象时的StackOverflowError

时间:2012-11-24 13:40:05

标签: java serialization stack-overflow

我想用这种方法来保护一个物体:

public void serializ(CRDT m) throws IOException {
    ByteArrayOutputStream byteOutput = new ByteArrayOutputStream();
    ObjectOutputStream stream = new ObjectOutputStream(byteOutput);
    stream.writeObject(m);
    sumMemory = byteOutput.size();

    stream.flush();
    stream.close();
    byteOutput.flush();
    byteOutput.close();
}

我有例外java.lang.StackOverflowError

Exception in thread "main" java.lang.StackOverflowError
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1169)
    at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1518)
    at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1483)
    at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1400)
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1158)
    at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1518)
    at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1483)
    at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1400)
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1158)
    at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1518)
    at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1483)
    at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1400)
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1158)
    at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1518)
    at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1483)
    at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1400)
    ...

我读了一些我需要重新实现writeObject / readObject方法的论坛。 这是唯一可行的解​​决方案吗?以及如何重新实现writeObject / readObject

我要序列化的对象是: http://pastebin.com/D1kEidtn

导致错误的两个类是: pastebin.com/Sb3X0Quqenter link description here

4 个答案:

答案 0 :(得分:4)

CRDT是序列化的对象m的超类。 错误是从CRDT派生的类似乎有自己的引用,导致无休止的递归 你可以在堆栈跟踪中看到它 Tipp通过使用调试器或在serialize()方法的beginn处添加System.out.println(m.getClass())来找出对象CRDT m的类。 然后,当您知道该类时,请检查该对象是否具有对自身的引用。

答案 1 :(得分:1)

您尚未发布具体课程,因此很难发现错误但是 简而言之,任何递归算法都可以溢出堆栈,堆栈是有限的。
对于深度嵌套的对象图,Java内置的serlialization需要过多的堆栈空间。
细节详情请参阅 http://c2.com/cgi/wiki?JavaSerializationIsBroken
http://c2.com/cgi/wiki?JavaSerializationAndTheStack

答案 2 :(得分:1)

我juste将-Xss512m添加到Netbeans并且它的工作:D

答案 3 :(得分:0)

顺便说一句,我有同样的问题,但看起来我的检查点持续时间太长了。看起来,Spark在写出来的时候会保持某种对象链接,如果持续时间太大,它会让堆栈溢出。