Сбор строки и мусора - PullRequest
       0

Сбор строки и мусора

4 голосов
/ 19 августа 2011

У меня есть метод в движке, который я использую (andengine):

public final void setText(String pString){...} 

мое приложение обновляет счет каждые 1 с от статического целого

mScoreText.setText(""+PlayerSystem.mScore);

Проблема в том, что этоКаждую секунду создается новый объект String, и через 1 минуту у меня есть 59 объектов String для сбора GC и дополнительные AbstractStringBuilders и init 's ...

Я нашел частичное решение на таких форумах, какthis:

private static StringBuilder mScoreValue = new StringBuilder("000000");

private static final char[] DIGITS = {'0','1','2','3','4','5','6','7','8','9'};

mScoreValue.setCharAt(0, DIGITS[(PlayerSystem.mScore% 1000000) / 100000]);
mScoreValue.setCharAt(1, DIGITS[(PlayerSystem.mScore% 100000) / 10000]);
mScoreValue.setCharAt(2, DIGITS[(PlayerSystem.mScore% 10000) / 1000]);
mScoreValue.setCharAt(3, DIGITS[(PlayerSystem.mScore% 1000) / 100]);
mScoreValue.setCharAt(4, DIGITS[(PlayerSystem.mScore% 100) / 10]);
mScoreValue.setCharAt(5, DIGITS[(PlayerSystem.mScore% 10)]);
mScoreText.setText(mScoreValue.toString());

, но основная проблема остается, .toString () возвращает новый объект каждый вызов

Есть ли способ решить эту проблему?

Ответы [ 3 ]

3 голосов
/ 19 августа 2011

Звучит как хороший кандидат на использование StringBuilder:

http://developer.android.com/reference/java/lang/StringBuilder.html

Или StringBuffer:

http://developer.android.com/reference/java/lang/StringBuffer.html

Причина:

StringBuffer используется для хранения символьных строк, которые будут изменены (объекты String не могут быть изменены).Он автоматически расширяется по мере необходимости.Связанные классы: String, CharSequence.

StringBuilder был добавлен в Java 5. Он идентичен во всех отношениях StringBuffer, за исключением того, что он не синхронизирован, что означает, что если к нему одновременно обращаются несколько потоков, существуетмогут быть проблемы.Для однопоточных программ, наиболее распространенный случай, позволяющий избежать накладных расходов на синхронизацию, делает StringBuilder немного быстрее.

Редактировать: одна вещь, с которой вам следует быть осторожным, это то, как вы используете любой выбранный класс SB.Причина в том, что (то же самое в .Net), если у вас есть подобное использование

StringBuilder sb = new StringBuilder(score.ToString() + "hello, world!");

У вас все еще есть две операции конкатата строк, вы, возможно, фактически делаете 3 строки там, одна для score.ToString(), один, чтобы превратить литерал "hello, world!" в строку, и тот, который содержит два соединенных вместе.Чтобы получить наилучшие результаты, вам нужно использовать методы SB добавления / вставки / замены.

3 голосов
/ 19 августа 2011

Насколько я знаю, нет способа обойти тот факт, что Strings являются неизменяемыми, и если ваш метод принимает строку, каждый раз необходимо будет создавать новую.

2 голосов
/ 19 августа 2011

Во-первых, 120 объектов за две минуты - это не то, о чем вам следует беспокоиться, если только они не очень большие.

Во-вторых, класс String содержит пул всех созданных строк. Итак, если вы делаете

 String a = new String("Nabucodonosor King of Babilonia");
 String b = new String("Nabucodonosor King of Babilonia");

затем Nabucodonosor King of Babilonia сохраняется только один раз в памяти (но на него указывают два объекта String). Подробности смотрите в String # intern ().

И наконец, как указывает Даниэль, поскольку строки являются неизменяемыми, обходных путей с использованием строк не существует. Вы могли бы сделать несколько трюков (проверить новое значение со старым значением и создать String, только если они отличаются), но я сомневаюсь, что они компенсируют дополнительную сложность.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...