这是我的java代码:
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)时,我得到错误StackOverflowError。我的问题是:为什么在我在内存中构建了对象后发生了这个错误?
假设索引的数据结构如下:
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;
}
为了避免递归调用,我覆盖了PostList的writeObject和readObject方法,因为它可能是一个很长的列表:
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();
}
}
然后我得到两个问题:
答案 0 :(得分:1)
如果没有看到你正在序列化的课程,很难知道,但我的猜测是对象图太复杂了。 Java的默认序列化机制通过对象图递归地工作;也就是说,如果你有一个带有对B的引用的对象A,并且你序列化了A,那么它必须走到B并序列化它。如果B然后引用C,并且C引用D,依此类推,那么递归算法可能必须深入到导致堆栈溢出。
如果这是造成问题的原因,您应该编写自己的readObject
和writeObject
,以避免这种递归构建,如果可能的话。
答案 1 :(得分:0)
如果你有一个深层嵌套的对象结构,那么需要一个深层栈来遍历。你应该在异常堆栈跟踪中看到这一点。堆栈空间ObjectOutputStream
和ObjectInputStream
并不是特别节俭。
如果您尝试序列化链接列表之类的内容,那么最好实现迭代列表而不是递归的readObject
和writeObject
方法。
答案 2 :(得分:0)
您的readObject()方法与您的writeObject()方法不匹配,因此它可能根本不起作用,并且您的writeObject()方法不会向默认序列化添加任何值。如果没有两者,你会更好。
递归问题来自PostNode类,而不是PostList类,你还没有真正做过任何事情。你需要一个明确遍历列表的PostNode.writeObject(),一个对称的readObject()方法和一个瞬态'next'字段。