序列化循环对象树 - 的StackOverflowError - 自定义序列化code需要 [英] Serialize cyclic object tree – StackOverflowError – custom serialization code needed

查看:205
本文介绍了序列化循环对象树 - 的StackOverflowError - 自定义序列化code需要的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想提出一个Android应用程序在那里我有一个双向循环对象树,我需要序列化填写BLOB字段中SQLite数据库。
但是默认的序列化实现抛出我的StackOverflowError(底部堆栈跟踪)。但是我在编写定制Java序列化code,以避免这种情况的经验。

我这个线程(<一个href=\"http://stackoverflow.com/questions/438875/stackoverflowerror-when-serializing-an-object-in-java\">StackOverflowError序列化Java中对象时),他谈到了问题,而是如何实现它在我的情况我真的没有任何想法:


  

这是可以定义这样的列表类writeObject()方法
  即,当第一链路被序列,简单地散步列表并
  序列化的各个环节反复;这将prevent默认
  被用于递归机制


这是我的对象模型(看1 / M,而不是其他标志):

这是我使用的序列化对象模型为一个字节数组方法(正确并不重要):

 字节公众[]连载(Object对象){
        字节[] BUF = NULL;
        尝试{
            ByteArrayOutputStream BOS =新ByteArrayOutputStream();
            的ObjectOutput出=新的ObjectOutputStream(BOS);
            out.writeObject(对象);
            out.close();
            BUF = bos.toByteArray();
        }赶上(IOException异常五){
            e.printStackTrace();
        }
        返回BUF;
    }

自定义序列化功能:

 私人无效的writeObject(java.io.ObjectOutputStream中出)抛出IOException
    //请帮助我这个code
}
私人无效的readObject(java.io.ObjectInputStream中的)抛出IOException异常,ClassNotFoundException异常{
    //请帮助我这个code
}

希望有人帮助我得到这个问题解决了。任何线索是AP preciated。

异常堆栈跟踪:

  20 05-25:28:16.231:E / AndroidRuntime(14451):致命异常:主要
05-25 20:28:16.231:E / AndroidRuntime(14451):java.lang.StackOverflowError
05-25 20:28:16.231:E / AndroidRuntime(14451):在java.util.IdentityHashMap.findIndex(IdentityHashMap.java:419)
05-25 20:28:16.231:E / AndroidRuntime(14451):在java.util.IdentityHashMap.get(IdentityHashMap.java:371)
05-25 20:28:16.231:E / AndroidRuntime(14451):在java.io.ObjectOutputStream.dumpCycle(ObjectOutputStream.java:471)
05-25 20:28:16.231:E / AndroidRuntime(14451):在java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1739)
05-25 20:28:16.231:E / AndroidRuntime(14451):在java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1689)
05-25 20:28:16.231:E / AndroidRuntime(14451):在java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1653)
05-25 20:28:16.231:E / AndroidRuntime(14451):在java.io.ObjectOutputStream.writeFieldValues​​(ObjectOutputStream.java:1143)
05-25 20:28:16.231:E / AndroidRuntime(14451):在java.io.ObjectOutputStream.defaultWriteObject(ObjectOutputStream.java:413)
05-25 20:28:16.231:E / AndroidRuntime(14451):在java.io.ObjectOutputStream.writeHierarchy(ObjectOutputStream.java:1241)
05-25 20:28:16.231:E / AndroidRuntime(14451):在java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1575)
05-25 20:28:16.231:E / AndroidRuntime(14451):在java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1847)
05-25 20:28:16.231:E / AndroidRuntime(14451):在java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1689)
05-25 20:28:16.231:E / AndroidRuntime(14451):在java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1653)
05-25 20:28:16.231:E / AndroidRuntime(14451):在java.io.ObjectOutputStream.writeFieldValues​​(ObjectOutputStream.java:1143)
05-25 20:28:16.231:E / AndroidRuntime(14451):在java.io.ObjectOutputStream.defaultWriteObject(ObjectOutputStream.java:413)
05-25 20:28:16.231:E / AndroidRuntime(14451):在java.io.ObjectOutputStream.writeHierarchy(ObjectOutputStream.java:1241)
05-25 20:28:16.231:E / AndroidRuntime(14451):在java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1575)
05-25 20:28:16.231:E / AndroidRuntime(14451):在java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1847)
05-25 20:28:16.231:E / AndroidRuntime(14451):在java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1689)
05-25 20:28:16.231:E / AndroidRuntime(14451):在java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1653)
05-25 20:28:16.231:E / AndroidRuntime(14451):在java.util.ArrayList.writeObject(ArrayList.java:651)
05-25 20:28:16.231:E / AndroidRuntime(14451):在java.lang.reflect.Method.invokeNative(本机方法)
05-25 20:28:16.231:E / AndroidRuntime(14451):在java.lang.reflect.Method.invoke(Method.java:507)
05-25 20:28:16.231:E / AndroidRuntime(14451):在java.io.ObjectOutputStream.writeHierarchy(ObjectOutputStream.java:1219)
05-25 20:28:16.231:E / AndroidRuntime(14451):在java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1575)
05-25 20:28:16.231:E / AndroidRuntime(14451):在java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1847)
05-25 20:28:16.231:E / AndroidRuntime(14451):在java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1689)
05-25 20:28:16.231:E / AndroidRuntime(14451):在java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1653)
05-25 20:28:16.231:E / AndroidRuntime(14451):在java.io.ObjectOutputStream.writeFieldValues​​(ObjectOutputStream.java:1143)
05-25 20:28:16.231:E / AndroidRuntime(14451):在java.io.ObjectOutputStream.defaultWriteObject(ObjectOutputStream.java:413)
05-25 20:28:16.231:E / AndroidRuntime(14451):在java.io.ObjectOutputStream.writeHierarchy(ObjectOutputStream.java:1241)
05-25 20:28:16.231:E / AndroidRuntime(14451):在java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1575)
05-25 20:28:16.231:E / AndroidRuntime(14451):在java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1847)
05-25 20:28:16.231:E / AndroidRuntime(14451):在java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1689)
05-25 20:28:16.231:E / AndroidRuntime(14451):在java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1653)
05-25 20:28:16.231:E / AndroidRuntime(14451):在java.io.ObjectOutputStream.writeFieldValues​​(ObjectOutputStream.java:1143)
05-25 20:28:16.231:E / AndroidRuntime(14451):在java.io.ObjectOutputStream.defaultWriteObject(ObjectOutputStream.java:413)
05-25 20:28:16.231:E / AndroidRuntime(14451):在java.io.ObjectOutputStream.writeHierarchy(ObjectOutputStream.java:1241)
05-25 20:28:16.231:E / AndroidRuntime(14451):在java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1575)
05-25 20:28:16.231:E / AndroidRuntime(14451):在java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1847)
05-25 20:28:16.231:E / AndroidRuntime(14451):在java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1689)
05-25 20:28:16.231:E / AndroidRuntime(14451):在java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1653)
05-25 20:28:16.231:E / AndroidRuntime(14451):在java.util.ArrayList.writeObject(ArrayList.java:651)
05-25 20:28:16.231:E / AndroidRuntime(14451):在java.lang.reflect.Method.invokeNative(本机方法)
05-25 20:28:16.231:E / AndroidRuntime(14451):在java.lang.reflect.Method.invoke(Method.java:507)
05-25 20:28:16.231:E / AndroidRuntime(14451):在java.io.ObjectOutputStream.writeHierarchy(ObjectOutputStream.java:1219)
05-25 20:28:16.231:E / AndroidRuntime(14451):在java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1575)
05-25 20:28:16.231:E / AndroidRuntime(14451):在java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1847)
05-25 20:28:16.231:E / AndroidRuntime(14451):在java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1689)
05-25 20:28:16.231:E / AndroidRuntime(14451):在java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1653)
05-25 20:28:16.231:E / AndroidRuntime(14451):在java.io.ObjectOutputStream.writeFieldValues​​(ObjectOutputStream.java:1143)
05-25 20:28:16.231:E / AndroidRuntime(14451):在java.io.ObjectOutputStream.defaultWriteObject(ObjectOutputStream.java:413)
05-25 20:28:16.231:E / AndroidRuntime(14451):在java.io.ObjectOutputStream.writeHierarchy(ObjectOutputStream.java:1241)
05-25 20:28:16.231:E / AndroidRuntime(14451):在java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1575)
05-25 20:28:16.231:E / AndroidRuntime(14451):在java.io.ObjectOutputStream.writeObject


解决方案

Java序列化正确处理循环图,但长期列表是一个问题。

如果我理解正确的话,你的问题是一个比你链接的文章中有些不同,造成约链表这篇文章的会谈没有正确的writeObject。虽然你目前正在使用的ArrayList,它已经存储的对象为平阵,并且还具有适当的writeObject

不过,如果我这样做是正确,会发生什么情况或多或少是这样的:

您开始序列化对象的,即序列化过程中遇到一个长长的清单,作为第一个元素,序列化对象B,对象B也有一个长长的清单,它需要的第一要素,说这是一个再次,因为它已经是正在连载它跳过A,所以它不会无限循环结束了,但然后去到B的名单,这是C,也是C有一个长长的清单的第二个目的,前两个元素是A和B再次,所以他们跳过,第三是D,其中也有一个列表....和SOOOO上。

由于这些步骤每一个都在叠层斯特斯几行,它填满了,即使它们是用适当的writeObject方法所有的ArrayList

这可能是这种情况,如果这些名单大规模进入相对大的数字,比起你的运行时间。这就是为什么我问的注释。也许一个办法可以解决,以避免一些序列列表(使他们短暂的),以及部分反序列化后重建他们。

I am making an android app where I have a bidirectional cyclic object tree that I need to serialize to fill in a blob field in a Sqlite database. But the default serialization implementation throws a StackOverflowError at me (stack trace at the bottom). But I have no experience in writing custom java serialization code to avoid this situation.

I this thread( StackOverflowError when serializing an object in Java ) he talks about the issue, but how to implement it in my case I haven’t really any idea:

It's possible to define a writeObject() method for such a list class that, when the first link is serialized, simply walks the list and serializes each link iteratively; this will prevent the default recursive mechanism from being used.

This is my object model(look at the 1/M, not the other signs):

This is the method I use to serialize the object model to a byte array (properly not that important):

public byte[] serialize(Object object) {
        byte[] buf = null;
        try {
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            ObjectOutput out = new ObjectOutputStream(bos);
            out.writeObject(object);
            out.close();
            buf = bos.toByteArray();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return buf;
    }

Custom serialization functions:

private void writeObject(java.io.ObjectOutputStream out) throws IOException {
    //please help me with this code
}
private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
    //please help me with this code
}

Hope someone help me getting this issue solved. Any clue is appreciated.

Exception stack trace:

05-25 20:28:16.231: E/AndroidRuntime(14451): FATAL EXCEPTION: main
05-25 20:28:16.231: E/AndroidRuntime(14451): java.lang.StackOverflowError
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.util.IdentityHashMap.findIndex(IdentityHashMap.java:419)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.util.IdentityHashMap.get(IdentityHashMap.java:371)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.io.ObjectOutputStream.dumpCycle(ObjectOutputStream.java:471)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1739)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1689)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1653)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.io.ObjectOutputStream.writeFieldValues(ObjectOutputStream.java:1143)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.io.ObjectOutputStream.defaultWriteObject(ObjectOutputStream.java:413)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.io.ObjectOutputStream.writeHierarchy(ObjectOutputStream.java:1241)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1575)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1847)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1689)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1653)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.io.ObjectOutputStream.writeFieldValues(ObjectOutputStream.java:1143)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.io.ObjectOutputStream.defaultWriteObject(ObjectOutputStream.java:413)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.io.ObjectOutputStream.writeHierarchy(ObjectOutputStream.java:1241)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1575)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1847)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1689)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1653)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.util.ArrayList.writeObject(ArrayList.java:651)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.lang.reflect.Method.invokeNative(Native Method)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.lang.reflect.Method.invoke(Method.java:507)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.io.ObjectOutputStream.writeHierarchy(ObjectOutputStream.java:1219)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1575)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1847)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1689)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1653)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.io.ObjectOutputStream.writeFieldValues(ObjectOutputStream.java:1143)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.io.ObjectOutputStream.defaultWriteObject(ObjectOutputStream.java:413)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.io.ObjectOutputStream.writeHierarchy(ObjectOutputStream.java:1241)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1575)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1847)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1689)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1653)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.io.ObjectOutputStream.writeFieldValues(ObjectOutputStream.java:1143)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.io.ObjectOutputStream.defaultWriteObject(ObjectOutputStream.java:413)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.io.ObjectOutputStream.writeHierarchy(ObjectOutputStream.java:1241)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1575)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1847)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1689)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1653)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.util.ArrayList.writeObject(ArrayList.java:651)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.lang.reflect.Method.invokeNative(Native Method)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.lang.reflect.Method.invoke(Method.java:507)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.io.ObjectOutputStream.writeHierarchy(ObjectOutputStream.java:1219)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1575)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1847)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1689)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1653)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.io.ObjectOutputStream.writeFieldValues(ObjectOutputStream.java:1143)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.io.ObjectOutputStream.defaultWriteObject(ObjectOutputStream.java:413)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.io.ObjectOutputStream.writeHierarchy(ObjectOutputStream.java:1241)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1575)
05-25 20:28:16.231: E/AndroidRuntime(14451):    at java.io.ObjectOutputStream.writeObject

解决方案

Java serialization handles cyclic graphs correctly, but long lists are a problem.

If I understand correctly, your problem is a bit different than the one in the article you linked, cause that article talks about linked lists without a proper writeObject .. while currently you are using ArrayLists, which already stores objects as a flat array, and also have a proper writeObject.

However, if I got it right, what happens is more or less this :

You start serializing object A, during that serialization it encounters a long list, takes the first element and serializes object B, object B also has a long list, it takes the first element, say it's A again, since it is already being serialized it skips A, so it does not end up in an endless loop, however then goes to the second object in the list of B, which is C, also C has a long list, the first two elements are A and B again, so they are skipped, the third is D, which also has a list .... and soooo on.

Since each one of these steps are a few lines in the stack stace, it fills up, even if they are all ArrayLists with a proper writeObject method.

This can be the case if those lists scale into relatively "big" numbers, compared to the runtime you have. That's why I asked in the comment. Maybe a solution can be found avoiding to serialize some lists (making them transient), and rebuilding them after the "partial" deserialization.

这篇关于序列化循环对象树 - 的StackOverflowError - 自定义序列化code需要的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆