總結平常Java開發常見優化策略,持續更新。html
調用方法時傳遞的參數以及在調用中建立的臨時變量都保存在棧中,速度較快,其餘變量,如靜態變量、實例變量等,都在堆中建立,速度較慢。另外,棧中建立的變量,隨着方法的運行結束,這些內容就沒了,不須要額外的垃圾回收。java
Java編程過程當中,進行數據庫鏈接、I/O流操做時務必當心,在使用完畢後,及時關閉以釋放資源。由於對這些大對象的操做會形成系統大的開銷,稍有不慎,將會致使嚴重的後果。而釋放資源最好的地方就是finally
代碼塊。算法
明確一個概念,對方法的調用,即便方法中只有一句語句,也是有消耗的,包括建立棧幀、調用方法時保護現場、調用方法完畢時恢復現場等。因此例以下面的操做:數據庫
for (int i = 0; i < list.size(); i++){
...
}複製代碼
建議替換爲:編程
for (int i = 0, length = list.size(); i < length; i++){
...
}複製代碼
這樣,在list.size()很大的時候,就減小了不少的消耗數組
例如:安全
String str = "aaa";
if (i == 1){
list.add(str);
}複製代碼
建議替換爲:服務器
if (i == 1){
String str = "aaa";
list.add(str);
}複製代碼
異常對性能不利。拋出異常首先要建立一個新的對象,Throwable接口的構造函數調用名爲fillInStackTrace()
的本地同步方法,fillInStackTrace()
方法檢查堆棧,收集調用跟蹤信息。只要有異常被拋出,Java虛擬機就必須調整調用堆棧,由於在處理過程當中建立了一個新的對象。異常只能用於錯誤處理,不該該用來控制程序流程。函數
好比ArrayList、LinkedLlist、StringBuilder、StringBuffer、HashMap、HashSet等等,以StringBuilder爲例:工具
能夠經過類(這裏指的不只僅是上面的StringBuilder)的構造函數來設定它的初始化容量,這樣能夠明顯地提高性能。好比StringBuilder吧,length表示當前的StringBuilder能保持的字符數量。由於當StringBuilder達到最大容量的時候,它會將自身容量增長到當前的2倍再加2,不管什麼時候只要StringBuilder達到它的最大容量,它就不得不建立一個新的字符數組而後將舊的字符數組內容拷貝到新字符數組中----這是十分耗費性能的一個操做。試想,若是能預估到字符數組中大概要存放5000個字符而不指定長度,最接近5000的2次冪是4096,每次擴容加的2無論,那麼:
這樣,既浪費內存空間又下降代碼運行效率。因此,給底層以數組實現的集合、工具類設置一個合理的初始化容量是錯不了的,這會帶來立竿見影的效果。可是,注意,像HashMap這種是以數組+鏈表實現的集合,別把初始大小和你估計的大小設置得同樣,由於一個table上只鏈接一個對象的可能性幾乎爲0。初始大小建議設置爲2的N次冪,若是能估計到有2000個元素,設置成new HashMap(128)、new HashMap(256)均可以。
例如:
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;
}複製代碼
移位操做雖然快,可是可能會使代碼不太好理解,所以最好加上相應的註釋。
例如:
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罷了,可是內存中只有一份,這樣就大大節省了內存空間了。
要知道,當某個對象被定義爲static的變量所引用,那麼gc一般是不會回收這個對象所佔有的堆內存的,如:
public class A{
private static B b = new B();
}複製代碼
此時靜態變量b的生命週期與A類相同,若是A類不被卸載,那麼引用B指向的B對象會常駐內存,直到程序終止
爲了清除再也不活動的會話,許多應用服務器都有默認的會話超時時間,通常爲30分鐘。當應用服務器須要保存更多的會話時,若是內存不足,那麼操做系統會把部分數據轉移到磁盤,應用服務器也可能根據MRU(最近最頻繁使用)算法把部分不活躍的會話轉儲到磁盤,甚至可能拋出內存不足的異常。若是會話要被轉儲到磁盤,那麼必需要先被序列化,在大規模集羣中,對對象進行序列化的代價是很昂貴的。所以,當會話再也不須要時,應當及時調用HttpSession的invalidate()方法清除會話。
參考文章:
https://www.cnblogs.com/xrq730/p/4865416.html
也歡迎關注個人公衆號:yizhuxiaozhan,二維碼: