開發Andorid應用的開發人員都知道,要盡量減少new關鍵字的使用,因為在手機上GC釋放一次記憶體是一件恐怖的事情,如果你查看一下調試記錄,你會發現GC釋放記憶體時有時會花上幾百毫秒的時間,可以想象,如果你開發的是遊戲,這時你的FPS會下降到多少。
雖然這個原則大家都知道,我們還是會看到一些開發人員會出現類似問題,這又是為什麼呢?呵呵,其實這是一些隱式的對象建立在作怪,看看以下代碼:
原則1:如果可能,請不要使用可變參數
1 publicvoid 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的壓力,所以,如果可能,請不要使用可變參數。
原則2:如果可能,請用StringBuilder代替字串的相加
我們來看一段代碼:
1 publicvoid 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();
這本身沒有什麼問題,但如果是如下就有意思了:
publicvoid 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來連結字串。
原則3:盡量將不變的東東設定為常數,特別是字串
較有效辦法是,你的代碼可以這樣來寫:
publicclass TestClass
{
privatestaticfinal String STR_HELLO="Hello!";
privatestaticfinal String STR_YOU_AGE_IS="you age is ";
privatestaticfinalint PIx100=(int)(Math.PI*100);
......
}
當然,即使這樣做了,後續對文本操作(如整數到文本轉換)任然是一件費時費力的或,原因是JAVA中,String是唯讀,任何String的內容操作均隱含了new關鍵字。作者在實際工作中只好採取了更笨笨的辦法,自己實現了一個GString類來替代常用的文本操作,其原理時使用預分配的位元組記憶體,只在需要時才轉換為String對象。
作者:汪峰 http://www.otlive.cn