开发Andorid应用的开发者都知道,要尽量减少new关键字的使用,因为在手机上GC释放一次内存是一件恐怖的事情,如果你查看一下调试记录,你会发现GC释放内存时有时会花上几百毫秒的时间,可以想象,如果你开发的是游戏,这时你的FPS会下降到多少。
虽然这个原则大家都知道,我们还是会看到一些开发者会出现类似问题,这又是为什么呢?呵呵,其实这是一些隐式的对象创建在作怪,看看以下代码:
1 public void test(Object ... args)
2 {
3 for (Object aObj: args)
4 {
5 .......
6 }
7 }
当外部调用时:
test( 1 , " some string " , false );
系统会自动创建一个临时的数组对象,类似于
Object[] args = new Object[]{ 1 , " some string " , false };
如果该函数经常被调用,则会极大增加GC的压力,所以,如果可能,请不要使用可变参数。
我们来看一段代码:
1 public void test2()
2 {
3 String tmp = " Hello! " + " some one. " ;
4 ......
5 }
系统会将这句翻译成为如下格式:
StringBuilder sb = new StringBuilder();
sb.append( " Hello! " );
sb.append( " some one " );
String tmp = sb.toString();
这本身没有什么问题,但如果是如下就有意思了:
public void test2()
{
String tmp = " Hello! " + " some one. " ;
....
tmp += " you age is " + 13 ;
....
}
这段代码等效于:
StringBuilder sb1 = new StringBuilder();
sb1.append( " Hello! " );
sb1.append( " some one. " );
tmp = sb1.toString();
...
StringBuilder sb2 = new StringBuilder();
sb2.append(tmp);
sb2.append( " your age is " );
sb2.append( 13 );
tmp = sb2.toString();
...
这样是不是悲剧,本来StringBuilder被无意义的重复创建了多次,期间还在数字转换到文本时创建了String,所以请直接使用显示的StringBuilder来链接字符串。
较有效的办法是,你的代码可以这样来写:
public class TestClass
{
private static final String STR_HELLO = " Hello! " ;
private static final String STR_YOU_AGE_IS = " you age is " ;
private static final int PIx100 = ( int )(Math.PI * 100 );
......
}
当然,即使这样做了,后续对文本操作(如整数到文本转换)任然是一件费时费力的或,原因是JAVA中,String是只读的,任何String的内 容操作均隐含了new关键字。作者在实际工作中只好采取了更笨笨的办法,自己实现了一个GString类来替代常用的文本操作,其原理时使用预分配的字节 内存,只在需要时才转换为String对象。
作者:汪峰 http://www.otlive.cn