2013-05-07 42 views
0

我有以下結構大的XML樹:Simpleframework java.lang.StackOverflowError的樹反序列化

<?xml version="1.0"?> 
<SampleElem xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <Children> 
     <SampleElem> 
     <Children/> 
     <Id>1</Id> 
     <Value>Test2</Value> 
     </SampleElem> 
    </Children> 
    <Id>-1</Id> 
    <Value>Test1</Value> 
</SampleElem> 

我試圖用simpleframework到反序列化:

Serializer serializer = new Persister(); 
SampleElem root = serializer.read(SampleElem.class, someStream, false); 

一段時間後停止的應用與錯誤。從設備登錄:

E/AndroidRuntime(13591): FATAL EXCEPTION: AsyncTask #1 
E/AndroidRuntime(13591): java.lang.RuntimeException: An error occured while executing doInBackground() 
E/AndroidRuntime(13591): at android.os.AsyncTask$3.done(AsyncTask.java:200) 
E/AndroidRuntime(13591): at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:274) 
E/AndroidRuntime(13591): at java.util.concurrent.FutureTask.setException(FutureTask.java:125) 
E/AndroidRuntime(13591): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:308) 
E/AndroidRuntime(13591): at java.util.concurrent.FutureTask.run(FutureTask.java:138) 
E/AndroidRuntime(13591): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088) 
E/AndroidRuntime(13591): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581) 
E/AndroidRuntime(13591): at java.lang.Thread.run(Thread.java:1019) 
E/AndroidRuntime(13591): Caused by: java.lang.StackOverflowError 
E/AndroidRuntime(13591): at java.lang.StringBuilder.append(StringBuilder.java:217) 
E/AndroidRuntime(13591): at java.lang.reflect.Modifier.toString(Modifier.java:285) 
E/AndroidRuntime(13591): at java.lang.reflect.Method.toString(Method.java:538) 
E/AndroidRuntime(13591): at java.lang.reflect.Method.equals(Method.java:361) 
E/AndroidRuntime(13591): at org.apache.harmony.lang.annotation.AnnotationFactory.invoke(AnnotationFactory.java:307) 
E/AndroidRuntime(13591): at $Proxy1.inline(Native Method) 
E/AndroidRuntime(13591): at org.simpleframework.xml.core.ElementListLabel.getConverter(ElementListLabel.java:160) 
E/AndroidRuntime(13591): at org.simpleframework.xml.core.CacheLabel.getConverter(CacheLabel.java:280) 
E/AndroidRuntime(13591): at org.simpleframework.xml.core.Composite.readVariable(Composite.java:604) 
E/AndroidRuntime(13591): at org.simpleframework.xml.core.Composite.readInstance(Composite.java:573) 
E/AndroidRuntime(13591): at org.simpleframework.xml.core.Composite.readUnion(Composite.java:549) 
E/AndroidRuntime(13591): at org.simpleframework.xml.core.Composite.readElement(Composite.java:532) 
E/AndroidRuntime(13591): at org.simpleframework.xml.core.Composite.readElements(Composite.java:445) 
E/AndroidRuntime(13591): at org.simpleframework.xml.core.Composite.access$400(Composite.java:59) 
E/AndroidRuntime(13591): at org.simpleframework.xml.core.Composite$Builder.read(Composite.java:1383) 
E/AndroidRuntime(13591): at org.simpleframework.xml.core.Composite.read(Composite.java:201) 
E/AndroidRuntime(13591): at org.simpleframework.xml.core.Composite.read(Composite.java:148) 
E/AndroidRuntime(13591): at org.simpleframework.xml.core.Traverser.read(Traverser.java:92) 
E/AndroidRuntime(13591): at org.simpleframework.xml.core.CompositeList.populate(CompositeList.java:175) 
E/AndroidRuntime(13591): at org.simpleframework.xml.core.CompositeList.read(CompositeList.java:120) 
E/AndroidRuntime(13591): at org.simpleframework.xml.core.Composite.readVariable(Composite.java:623) 
E/AndroidRuntime(13591): at org.simpleframework.xml.core.Composite.readInstance(Composite.java:573) 
E/AndroidRuntime(13591): at org.simpleframework.xml.core.Composite.readUnion(Composite.java:549) 
E/AndroidRuntime(13591): at org.simpleframework.xml.core.Composite.readElement(Composite.java:532) 
E/AndroidRuntime(13591): at org.simpleframework.xml.core.Composite.readElements(Composite.java:445) 
E/AndroidRuntime(13591): at org.simpleframework.xml.core.Composite.access$400(Composite.java:59) 
E/AndroidRuntime(13591): at org.simpleframework.xml.core.Composite$Builder.read(Composite.java:1383) 
E/AndroidRuntime(13591): at org.simpleframework.xml.core.Composite.read(Composite.java:201) 
E/AndroidRuntime(13591): at org.simpleframework.xml.core.Composite.read(Composite.java:148) 
E/AndroidRuntime(13591): at org.simpleframework.xml.core.Traverser.read(Traverser.java:92) 
E/AndroidRuntime(13591): at org.simpleframework.xml.core.CompositeList.populate(CompositeList.java:175) 
E/AndroidRuntime(13591): at org.simpleframework.xml.core.CompositeList.read(CompositeList.java:120) 
E/AndroidRuntime(13591): at org.simpleframework.xml.core.Composite.readVariable(Composite.java:623) 
E/AndroidRuntime(13591): at org.simpleframework.xml.core.Composite.readInstance(Composite.java:573) 
E/AndroidRuntime(13591): at org.simpleframework.xml.core.Composite.readUnion(Composite.java:549) 
E/AndroidRuntime(13591): at org.simpleframework.xml.core.Composite.readElement(Composite.java:532) 
E/AndroidRuntime(13591): at org.simpleframework.xml.core.Composite.readElements(Composite.java:445) 
E/AndroidRuntime(13591): at org.simpleframework.xml.core.Composite.access$400(Composite.java:59) 
E/AndroidRuntime(13591): at org.simpleframework.xml.core.Composite$Builder.read(Composite.java:1383) 
E/AndroidRuntime(13591): at org.simpleframework.xml.core.Composite.read(Composite.java:201) 
E/AndroidRuntime(13591): at org.simpleframework.xml.core.Composite.read(Composite.java:148) 
E/AndroidRuntime(13591): at org.simpleframework.xml.core.Traverser.read(Traverser.java:92) 
E/AndroidRuntime(13591): at org.simpleframework.xml.core.CompositeList.populate(CompositeList.java:175) 
E/AndroidRuntime(13591): at org.simpleframework.xml.core.CompositeList.read(CompositeList.java:120) 
E/AndroidRuntime(13591): at org.simpleframework.xml.core.Composite.readVariable(Composite.java:623) 
E/AndroidRuntime(13591): at org.simpleframework.xml.core.Composite.readInstance(Composite.java:573) 
E/AndroidRuntime(13591): at org.simpleframework.xml.core.Compos 

數據是完全正確的,輸入xml是完全有效的。你有什麼想法?

謝謝!

UPDATE:

什麼TreeStrategy?它應該如何使用?你有沒有例子?

+0

可能是內存問題,因爲樹太大?你是否嘗試過較小的? – Evans 2013-05-07 21:45:45

+0

是的,樹的分層長度很大,但我無法分割它。我需要處理整棵樹。較小的樹木很好。 – asolovyov 2013-05-07 21:54:20

+0

然後嘗試使用-Xss增加JVM的堆棧大小。檢查這個鏈接中的問題和答案http://stackoverflow.com/questions/3700459/how-to-increase-to-java-stack-size – Evans 2013-05-07 22:00:28

回答

0

在我的情況最令人滿意的解決方案是重寫我的XML模式線性結構。它減少了對反序列化樹的總內存要求。

感謝所有的評論。

0

嘗試增加存儲器,包括這些參數:

-Xmx1024m -Xss1024m 

您可以指定的內存量奉獻。

+0

我無法使用它,我正在使用android。另外,可以放大xml的大小。 – asolovyov 2013-05-07 22:10:22

0

通過將以下JVM參數更改堆棧大小:

-Xss128m 

因爲,你的XML文件很大,解析器似乎是在做一個遞歸(可能是因爲<SampleElem>可以<SampleElem>作爲一個孩子)堆棧大小需要增加。默認大小僅爲512 KB。

注意:如果解析仍然失敗,則爲128m;保持加倍的大小(如256米,然後512米等)

+0

它不能在Android上使用。 – asolovyov 2013-05-07 22:12:48

+1

啊,我跳了槍!無論如何,一般來說,如果解析帶有內存約束的XML,應該使用SAX解析器(基於事件),而不是嘗試在內存中表示完整XML輸入的DOM。 – 2013-05-07 22:23:00

+0

您是否知道任何適用的庫,用於通過SAX從xml自動反序列化爲對象? – asolovyov 2013-05-07 22:33:03

1

您不能在Android上更改默認堆棧大小或現有線程的堆棧大小。但是,您可以在創建線程時設置堆棧大小。使用完整的構造函數:

public Thread(ThreadGroup group, Runnable runnable, String threadName, long stackSize) 

您可以將堆棧大小設置爲256KB。

因此,您的情況下的策略是創建一個深層堆棧的新線程,並在該線程上運行此分析代碼。