35 個 Java 代碼性能優化總結 10-20


11、乘法和除法使用移位操作

例如:

for (val = 0; val < 100000; val += 5) 
{ 
a = val * 8; 
b = val / 2; 
}

用移位操作可以極大地提高性能,因爲在計算機底層,對位的操作是最方便、最快的,因此建議修改爲:

for (val = 0; val < 100000; val += 5) 
{ 
a = val << 3; 
b = val >> 1; 
}

移位操作雖然快,但是可能會使代碼不太好理解,因此最好加上相應的註釋。


12、循環內不要不斷創建對象引用

例如:

for (int i = 1; i <= count; i++) 
{ 
Object obj = new Object(); 
}

這種做法會導致內存中有count份Object對象引用存在,count很大的話,就耗費內存了,建議爲改爲:

Object obj = null;
for (int i = 0; i <= count; i++)
{ 
    obj = new Object(); 
}

這樣的話,內存中只有一份Object對象引用,每次new Object()的時候,Object對象引用指向不同的Object罷了,但是內存中只有一份,這樣就大大節省了內存空間了。


13、基於效率和類型檢查的考慮,應該儘可能使用array,無法確定數組大小時才使用ArrayList


14、儘量使用HashMap、ArrayList、StringBuilder,除非線程安全需要,否則不推薦使用Hashtable、Vector、StringBuffer,後三者由於使用同步機制而導致了性能開銷

15、不要將數組聲明爲public static final

因爲這毫無意義,這樣只是定義了引用爲static final,數組的內容還是可以隨意改變的,將數組聲明爲public更是一個安全漏洞,這意味着這個數組可以被外部類所改變


16、儘量在合適的場合使用單例

使用單例可以減輕加載的負擔、縮短加載的時間、提高加載的效率,但並不是所有地方都適用於單例,簡單來說,單例主要適用於以下三個方面:

(1)控制資源的使用,通過線程同步來控制資源的併發訪問

(2)控制實例的產生,以達到節約資源的目的

(3)控制數據的共享,在不建立直接關聯的條件下,讓多個不相關的進程或線程之間實現通信


17、儘量避免隨意使用靜態變量

要知道,當某個對象被定義爲static的變量所引用,那麼gc通常是不會回收這個對象所佔有的堆內存的,如:

public class A 
{ 
  private static B b = new B(); 
}

此時靜態變量b的生命週期與A類相同,如果A類不被卸載,那麼引用B指向的B對象會常駐內存,直到程序終止


18、及時清除不再需要的會話

爲了清除不再活動的會話,許多應用服務器都有默認的會話超時時間,一般爲30分鐘。當應用服務器需要保存更多的會話時,如果內存不足,那麼操作系統 會把部分數據轉移到磁盤,應用服務器也可能根據MRU(最近最頻繁使用)算法把部分不活躍的會話轉儲到磁盤,甚至可能拋出內存不足的異常。如果會話要被轉 儲到磁盤,那麼必須要先被序列化,在大規模集羣中,對對象進行序列化的代價是很昂貴的。因此,當會話不再需要時,應當及時調用HttpSession的 invalidate()方法清除會話。


19、實現RandomAccess接口的集合比如ArrayList,應當使用最普通的for循環而不是foreach循環來遍歷

這是JDK推薦給用戶的。JDK API對於RandomAccess接口的解釋是:實現RandomAccess接口用來表明其支持快速隨機訪問,此接口的主要目的是允許一般的算法更改 其行爲,從而將其應用到隨機或連續訪問列表時能提供良好的性能。實際經驗表明,實現RandomAccess接口的類實例,假如是隨機訪問的,使用普通 for循環效率將高於使用foreach循環;反過來,如果是順序訪問的,則使用Iterator會效率更高。可以使用類似如下的代碼作判斷:

if (list instanceof RandomAccess){
    for (int i = 0; i < list.size(); i++){
}
}else{
   Iterator<?> iterator = list.iterable(); 
   while (iterator.hasNext()){iterator.next()
   }
}

foreach循環的底層實現原理就是迭代器Iterator,參見Java語法糖1:可變長度參數以及foreach循環原理。所以後半句”反過來,如果是順序訪問的,則使用Iterator會效率更高”的意思就是順序訪問的那些類實例,使用foreach循環去遍歷。


20、使用同步代碼塊替代同步方法

這點在多線程模塊中的synchronized鎖方法塊一文中已經講得很清楚了,除非能確定一整個方法都是需要進行同步的,否則儘量使用同步代碼塊,避免對那些不需要進行同步的代碼也進行了同步,影響了代碼執行效率。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章