2013-12-02 4 views
2

У меня есть TabHost с TextViews, связанный с каждой вкладкой, в контексте Activity. В настоящее время существует также AsyncTask, которая управляет сокетом TCP и когда получает какую-то информацию, она отправляется главному обработчику Activity, который вызывает метод для добавления текста в текущий TextView.Ошибка утечки памяти

Ну, через некоторое время (около 5 минут) работы я замечаю, как он начинает висит, и, наконец, я получаю ANR. Поэтому я установил Memory Analyzer для Eclipse и в сочетании с DDMS, я смог узнать, что, по-видимому, является узким местом, но не как с этим бороться.

Используя ранее упомянутые инструменты, я был в состоянии увидеть сотни строк, как те, на этой картинке:

enter image description here

BTW: Там странная деталь в этой картинке, Ид нить всегда 1; не должно ли быть разным для каждого потока, поскольку append вызывается в разных потоках?

Эти сотни строк ссылаются на два «добавления», которые вы можете увидеть в коде выше. Я новичок в мире нитей, поэтому, если вы видите что-то странное, я буду благодарен за любые советы. Это код, где узкое место:

// tab = is the name of the tab where to append the new text 
// line = the line to append; it may contain spans, colors, bold text, etc... that's why it's a SpannableStringBuilder 
// ColorLine is a method that just returns a SpannableStringBuilder-formatted string 

synchronized private static void Write2Tab(final String tab, final SpannableStringBuilder line) { 
    final TabHost lth = (TabHost) activity.findViewById(android.R.id.tabhost); 
    final TextView tabContent = (TextView) lth.getCurrentView(); 

    new Thread(new Runnable() { 
    public void run() { 
     String curtab = getCurrentTabName(); 

     // If the current tab is the one where we need to write, we do 
     if (tab.equalsIgnoreCase(curtab)) { 
     activity.runOnUiThread(new Runnable() { 
      public void run() { 
      tabContent.append(linea); 
      tabContent.append((ColorLine("\n", Color.WHITE, false, 0, 1))); 
      } 
     }); 
     } 
    } 
    }).start(); 

    [...] 
} 

У меня было еще 2 утечки памяти в моем коде, что я был в состоянии исправить, но отправным это одно, чтобы быть немного трудно ... Любые идеи о том, почему это происходит и как это исправить?

--------------- EDIT ---------------

После нескольких дней расстраивает исследования на предмет утечек в мое приложение, я узнал, что было больше одного. Мне удалось решить их, тот, который я изначально разместил, был связан с сообщением Джона Винта, возникла проблема с буферизацией, которая сделала существенное накопление объектов SpannableStringBuilder в TextView, поэтому я принимаю его сообщение. Теперь у меня другая проблема с другой любопытной утечкой, но она не имеет ничего общего с исходным сообщением, поэтому я собираюсь открыть новый вопрос.

+0

Где вы звоните - Write2Tab? –

+0

Насколько я знаю, утечка памяти в Java невозможна. Вся память, которую вы занимаете, находится под вашим контролем, иначе сборщик мусора освободит ее. – HAL9000

+0

@ HAL9000 Если вы продолжаете выделять память, ваше приложение будет медленным из-за работы garbagecollector. –

ответ

0

Насколько велика StringBuilder?

Если нить застряла на 253, как показано в вашей куче немой, все, что я могу придумать, это то, что у вас заканчивается пустое пространство и достигается предельный накладной GC.

Если это так, вам понадобится буфер StringBuilder (т.е. если длина> N, чем удалить самую старую строку, где N - достаточно большое число, чтобы иметь историю, но достаточно маленькую, чтобы предотвратить OOM).

+0

Я на самом деле это делаю, каждая вкладка имеет ограничение на 30 строк. Если он превысит этот предел, удаляются самые старые текущие строки - 30. Это была еще одна утечка, но я смог ее исправить. – nKn

+0

@ user3001496 Хорошо. К сожалению, информации недостаточно. Похоже, что все должно быть выстроено для выделения при необходимости. –

+0

Обратите внимание на ThreadId: 1 может означать только поток пользовательского интерфейса. Когда вы говорите 'runOnUiThread', он помещает задачу в очередь и будет запускать ее позже. –

Смежные вопросы