零碎筆記(八)
java程式啟動時新增引數-XX:+AlwaysPreTouch
啟動時就把引數裡說好了的記憶體全部舔一遍,可能令得啟動時慢上一點,但後面訪問時會更流暢,比如頁面會連續分配,比如不會在晉升新生代到老生代時才去訪問頁面使得GC停頓時間加長。ElasticSearch和Cassandra都打開了它。
Thread#setUncaughtExceptionHandler()
方法可用來設定未捕捉的異常處理器。
如果執行緒使用相同的未捕捉的異常處理器,可以使用Thread.setDefaultUncaughtExceptionHandler()
設定全域性的。
資料庫連線有“8小時問題”,所以Spring 資料庫資料來源配置時,destroy-method="close"一定要加上。“8小時問題”是指一個連線空閒8小時資料庫會自動關閉,而資料來源並不知道。
高併發下,可以testOnBorrow
testWhileIdle
設定為true,這樣就會定時對後臺空連結進行檢測發現無用連線就會清除掉,不會每次都去都去檢測是否8小時的空連結。 當複製大量資料時,使用System.arraycopy()命令。
慎用異常,異常對效能不利。
丟擲異常首先要建立一個新的物件,Throwable介面的建構函式呼叫名為fillInStackTrace()
的本地同步方法,fillInStackTrace()
方法檢查堆疊,收集呼叫跟蹤資訊。只要有異常被丟擲,Java虛擬機器就必須調整呼叫堆疊,因為在處理過程中建立了一個新的物件。
異常只能用於錯誤處理,不應該用來控制程式流程。
基於效率和型別檢查的考慮,應該儘可能使用array,無法確定陣列大小時才使用ArrayList。
ArrayList刪除元素時, 從尾部開始遍歷,可大大提升執行效率
迴圈內不要不斷建立物件引用,例如:
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罷了,但是記憶體中只有一份,這樣就大大節省了記憶體空間了。
java不支援建立泛型陣列,可以使用Array.newInstance
來實現:
// http://blog.csdn.net/orzlzro/article/details/7017435
public static <T> T[] test2(int length, Class<T> newType) {
// T t = new T(); 編譯錯誤
// T[] wrong = new T[length]; 編譯錯誤
// T[] newArray = (T[]) new Object[length]; 執行時ClassCastException
// 參考Arrays.copyOf
T[] newArray = (T[]) Array.newInstance(newType, length);
return newArray;
}
Tomcat最大連線數取決於maxConnections值加上acceptCount這個值,在連線數達到了maxConenctions之後,tomcat仍會保持住連線,但是不處理,等待其它請求處理完畢之後才會處理這個請求。
看原始碼時,常常會看到這種寫法,有啥好處?
final E[] items = this.items;
final ReentrantLock lock = this.lock;
1、final的資料不可變,因此更安全,防止意外修改,閱讀程式碼時更清晰,是一種好的程式設計習慣;
2、更快,因為每次都直接this.items會發生如下操作(位元組碼錶示):
aload_0 //0 表示當前物件
getfield #xxx; //得到當前物件的items
從位元組碼可以看出需要兩條指令; 如果 final E[] items = this.items;
如果接下來使用的話,直接從堆疊取items的引用,更快。