Java 如何处理序列化大对象时发生的StackOverflower错误?
以下是我的java代码:Java 如何处理序列化大对象时发生的StackOverflower错误?,java,serialization,stack-overflow,Java,Serialization,Stack Overflow,以下是我的java代码: FileOutputStream fos = null; ObjectOutputStream out = null; try { fos = new FileOutputStream(pathName); out = new ObjectOutputStream(fos); out.writeObject(index); out.close(); fos.clos
FileOutputStream fos = null;
ObjectOutputStream out = null;
try {
fos = new FileOutputStream(pathName);
out = new ObjectOutputStream(fos);
out.writeObject(index);
out.close();
fos.close();
} catch (IOException e) {
LogManager.writeLogToFile(e.getMessage());
e.printStackTrace();
}
这个索引是我自己倒排文档索引的一个实例。我已经在内存中构建了对象索引,但是当我将其传递给方法writeObject(index)时,我得到了错误StackOverflowerError。我的问题是:在我在内存中构建对象之后,为什么会发生此错误
假设索引的数据结构如下:
class InvertedIndex{
private HashMap<String, PostList> index;
}
class PostList{
private int size;
private PostNode first;
}
class PostNode{
private String key;
private double weight;
private PostNode next;
}
然后我有两个问题:
- out.writeObject(临时);因为temp有一个对下一个节点的引用,所以当我写temp时,递归调用也会发生。即使我用defaultWriteObject覆盖PostNode的writeObject方法,同样的情况也会继续。我说得对吗?如果是这样,我可以做些什么来避免这种递归调用
- 如何覆盖readObject()方法李>
- 如果看不到正在序列化的类,就很难知道,但我猜对象图太复杂了。Java的默认序列化机制通过对象图递归工作;也就是说,如果对象A引用了B,并且序列化了A,那么它必须走到B并序列化它。如果B然后引用C,C引用D,依此类推,那么递归算法可能必须深入到导致堆栈溢出的程度
如果这就是导致问题的原因,您应该编写自己的
和readObject
,尽可能避免这种递归构建。如果您有一个深度嵌套的对象结构,则需要一个深度堆栈来遍历。您应该在异常堆栈跟踪中看到这一点writeObject
和ObjectOutputStream
在堆栈空间方面并不特别节省 如果您试图序列化链表之类的内容,那么最好实现迭代列表而不是递归的ObjectInputStream
和readObject
方法。您的readObject()方法与writeObject()方法不匹配,因此它可能根本不起作用,而您的writeObject()方法方法不会向默认序列化添加任何值。没有这两个你会过得更好writeObject
递归问题来自PostNode类,而不是PostList类,您实际上还没有对此做任何事情。您需要一个显式遍历列表的PostNode.writeObject()、一个对称的readObject()方法和一个临时的“next”字段。如果不知道索引是什么,很难说。可能重复:这也可以帮助你:我想我的问题是,根据你的建议,索引的帖子列表是一个长链表。谢谢你的帮助@ASSYLASIS我尝试根据您的建议覆盖方法
和readObject
,我遇到了上面显示的新问题。你能告诉我如何覆盖这两种方法,或者给我网上的资源吗?我从中发现了一些东西,但我认为我的问题更复杂@Tom Hawtin-TackLine但是设置writeObject
字段瞬态意味着下一个字段将不会被序列化。如果是这样,当我反序列化一个post节点时,我如何知道下一个节点是谁@EJP@jerry_sjtu它将由循环序列化。事实上,您当前的代码对列表进行了两次序列化:一次是因为非瞬态的“next”字段,另一次是因为lop,它位于错误的类中。Yur反序列化循环应将下一个字段设置为流中的下一个对象,如果为null,则中断。next
class PostList{ private void writeObject(ObjectOutputStream out) throws IOException{ PostNode temp = first; while(temp != null){ out.writeObject(temp); temp = temp.getNext(); } } private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException{ in.defaultReadObject(); } }