字符串和垃圾收集

时间:2011-08-18 21:48:32

标签: java android garbage-collection

我在引擎中有一个方法我正在使用(andengine):

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

我的应用是从静态int

每1秒更新一次得分
mScoreText.setText(""+PlayerSystem.mScore);

问题在于这种方式每秒都会创建一个新的String对象,1分钟后我有66个String对象要通过GC和其他AbstractStringBuilders和init来收集......

我在andengine论坛上发现了一个部分解决方案:

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 个答案:

答案 0 :(得分:3)

据我所知,没有办法解决Strings不可变的事实,如果你的方法采用String,每次都必须创建一个新的。

答案 1 :(得分:3)

这听起来像是使用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的Append / insert / replace方法。

答案 2 :(得分:2)

首先,两分钟内120个物体是你不应该担心的,除非它们非常大。

其次,String类包含创建的所有字符串的池。所以,如果你这样做

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

然后Nabucodonosor King of Babilonia只在内存中存储一​​次(但有两个String对象指向它)。检查字符串#intern()以获取详细信息。

最后,正如Daniel指出的那样,因为Strings是不可变的,所以没有使用Strings的解决方法。你可以做一些技巧(用旧值检查新值,只在它们不同的情况下创建String)但我怀疑它们会补偿增加的复杂性。