Java – String and garbage collection

String and garbage collection… here is a solution to the problem.

String and garbage collection

I have a method in the engine (and engine) I’m using:

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

My app updates the score from static int every 1 second

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

The problem is that a new String object is created every second, and after 1 minute I have 59 String objects to be collected by GC and other AbstractStringBuilders and init…

I found a partial solution like this on the AndEngine forum:

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());

But the main problem remains, .toString() returns a new object with each call

Is there any way to fix it?

Solution

This sounds like a good choice for using StringBuilder:

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

Or StringBuffer:

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

The reasoning is:

StringBuffer is used to store the string that will be changed (the String object cannot be changed). It automatically scales as needed. Related classes: String, CharSequence.

StringBuilder, added in Java 5, is exactly the same as StringBuffer, except it’s not synchronous, which means that if multiple threads access it at the same time, you’ll be in trouble. This is the most common case for single-threaded programs, and avoiding synchronization overhead makes StringBuilder slightly faster.

Edit:
One thing you have to pay attention to is how to use the SB class of your choice.
The reason is (as well in .NET) if you have such usage

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

You still have 2 string concatenation operations, and you might actually make 3 strings there, one for , one for score.ToString()converting literals "hello, world !" into a string, and one containing two strings concatenated together.
For best results, you need to use SB’s Append/insert/replace method.

Related Problems and Solutions