應用程序性能直接受到垃圾收集(GC)的頻率和持續時間的影響,如果在GC策略調優到達瓶頸后,性能的差別就會產生在代碼的編寫質量了。下面就來說說GC友好代碼的幾個技巧。對GC感興趣的同學可以參加java培訓,可以獲得快速有效的學習。
技巧1:預測收集容量
所有標準Java集合,以及大多數自定義和擴展實現(如Trove和Google的Guava)都使用底層數組(基于原語或基于對象)。由于數組在分配后大小是不可變的,因此在許多情況下,向集合中添加項可能會導致刪除舊的底層數組,而選擇新分配的較大數組。
大多數集合實現都試圖優化此重新分配過程,并將其保持在攤銷最小值,即使未提供集合的預期大小。但是,通過在構建時為集合提供其預期大小,可以實現最佳效果。
技巧2:直接處理流程
在處理數據流時,例如從文件讀取的數據或通過網絡下載的數據,通常會看到以下內容:
然后,可以將生成的字節數組解析為XML文檔、JSON對象或協議緩沖區消息,以列舉一些流行選項。
在處理大型文件或大小不可預測的文件時,這顯然是一個壞主意,因為如果JVM無法實際分配整個文件大小的緩沖區,它會使我們暴露出OutOfMemory錯誤。在java培訓中,有很多關于GC的培訓課程,在專業老師的教學指導下,可以很全面地掌握GC的相關知識和技能。
更好的方法是使用適當的InputStream(本例中為FileInputStream)并將其直接提供給解析器,而無需首先將整個內容讀入字節數組。所有主要庫都公開API以直接解析流,例如:
技巧3:使用不可變對象
不變性有許多優點。它對垃圾收集的影響很少得到應有的關注。
不可變對象是一個對象,其字段(在本例中特別是非基本字段)在對象構造后無法修改。
不變性意味著不可變容器引用的所有對象都是在容器構造完成之前創建的。在GC術語中:容器至少和它所持有的最年輕引用一樣年輕。這意味著,當對年輕代執行垃圾收集循環時,GC可以跳過位于較老代中的不可變對象,因為它確定這些對象不能引用正在收集的代中的任何對象。
要掃描的對象越少意味著要掃描的內存頁越少,而要掃描的內存頁越少意味著GC周期越短,這意味著GC暫停時間越短,總體吞吐量越好。想學習java技術的同學,不妨報個Java培訓班,有明確清晰的學習路線,理論知識+實戰操作,可以獲得快速提升。