簡體   English   中英

StringBuilder setLength(0)處出現奇怪的OutOfMemoryError

[英]Strange OutOfMemoryError at StringBuilder setLength(0)

似乎沒有人報告過類似情況...我完全不知道發生了什么...

我有一個大小為8Mb的StringBuilder來處理較大的String result 我正在嘗試重用StringBuilder 我認為將length設置為0只會重置計數器而不分配新的內存嗎?

try {
      //result.length() around 4Mb
        StringBuilder sBuilder = new StringBuilder(result.length());
        result = DoSomethingToResult1(sBuilder, result); //shrink result a bit using replaceAll

        try {

            sssBuilder.setLength(0);
            result = DoSomethingToResult2(sBuilder, result); //shrink result further using replaceAll
        } catch (OutOfMemoryError e) {
             Log.d(TAG, "Out of Memory on 2");
        }

        try {
            sBuilder.setLength(0);  //OutOfMemory thrown here.          
            result = DoSomethingToResult3(sBuilder, result); //shrink result even further using replaceAll
        } catch (OutOfMemoryError e) {
             Log.d(TAG, "Out of Memory on 3");
        }

    } catch (OutOfMemoryError e) {
                Log.d(TAG, "Cannot create sBuilder");
    }

該進程通常死在第二個setLength(0) ,有時死在第一個setLength(0) ,但是它總是可以在開始時創建sBuilder

DoSomethingToResult ,我將result分成100Kb大小的塊,並一一追加到sBuilder ,返回sBuilder.toString()。 因此問題不是來自replaceAll 而且由於它通過了​​第一個過程,所以我也不認為toString()就是問題。

我試過了:

sBuilder.setLength(0);
System.gc();
try{
    Thread.sleep(1000);
}catch(Exception e){};

要么

System.gc();
try{
    Thread.sleep(1000);
}catch(Exception e){};
sBuilder.setLength(0);

都失敗了。

日志輸出:

E/dalvikvm-heap(27130): Out of memory on a 8723792-byte allocation.
I/dalvikvm(27130): "AsyncTask #1" prio=5 tid=11 RUNNABLE
I/dalvikvm(27130):   | group="main" sCount=0 dsCount=0 obj=0x42036a18 self=0x51c2eb08
I/dalvikvm(27130):   | sysTid=27151 nice=10 sched=0/0 cgrp=apps/bg_non_interactive handle=1371731208
I/dalvikvm(27130):   | schedstat=( 0 0 0 ) utm=197 stm=17 core=1
I/dalvikvm(27130):   at java.lang.AbstractStringBuilder.setLength(AbstractStringBuilder.java:~567)
I/dalvikvm(27130):   at java.lang.StringBuilder.setLength(StringBuilder.java:44)

將length設置為0不會自動調用GC來啟動。您可以做的是循環並調用System.gc,然后等待一段時間,直到可用內存增加。 然后退出循環,繼續進行下一個過程。

您也可以嘗試分配新的構建器,而不是在每次迭代中清除緩沖區。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM