
1. 減少記憶體使用
1.1. 減少堆記憶體的使用
1.1.1. 使用更少的記憶體意味著堆被填滿的頻率會降低,需要的GC周期會更少,其效果也可以成倍增強
1.1.2. 更少的新生代回收意味著物件的晉升年齡增加的頻率降低
1.1.3. 物件晉升到老年代的可能性也降低了
1.1.4. Full GC周期(或者并發GC周期)的數量將減少
1.2. 方法
1.2.1. 減小物件大小
1.2.2. 使用物件的延遲初始化
1.2.3. 使用標準化物件
2. 減小物件大小
2.1. 可以提高GC的效率
2.2. 即使實體變數是null,也會消耗物件類內的空間
2.3. 讓物件更小
2.3.1. 不太可能將堆的大小增加10%
2.3.2. 將堆中一半物件的大小減小20%可以達到相同的目標
2.3.2.1. Java 11對String物件進行了這樣的優化
2.3.2.2. Java 11的用戶可以將堆的最大大小設定得比Java 8要求的小25%,而不會對GC或性能產生影響
2.4. 物件對齊和物件大小
2.4.1. 物件的大小總是被填充到8位元組的倍數
2.4.2. 在物件中消除一些實體欄位或減小一些欄位的大小,可能會產生收益,也可能不會,但我們沒有理由不這么做
2.4.3. jol工具
2.4.3.1. 可以計算物件的大小
2.5. 時間與空間的權衡
2.5.1. 物件欄位存盤的是基于一些資料計算出的結果
2.5.1.1. 使用記憶體(空間)存盤這個值
2.5.1.2. 花費時間(CPU周期)在需要的時候計算這個值
2.5.1.2.1. 如果減少GC是目標,大多數人可能更傾向于重新計算
2.5.2. 適用于CPU時間
2.5.2.1. 使用額外的記憶體會導致GC消耗更多的CPU周期
3. 使用延遲初始化
3.1. 只有在常用路徑不會初始化變數時,才應該使用延遲初始化
3.1.1. 最好只在相關操作使用得不那么頻繁時使用
3.1.2. 操作很常用,那就不能節省記憶體了
3.1.2.1. 因為記憶體總是會被分配
3.2. 對于使用執行緒安全物件的代碼,延遲初始化時應該使用雙重檢查鎖
3.3. 同步瓶頸
3.3.1. 通過慣用的雙重檢查鎖來解決
3.3.2. 實體變數必須被宣告為volatile
3.3.3. 將實體變數賦值到區域變數會帶來輕微的性能提升
3.4. 設為null來及早清理
3.4.1. eagerly deinitializing
3.4.2. 在有限的情況下有用
3.4.3. 顯式地將一個物件參考設定為null基本不會給性能帶來什么好處
3.4.4. 如果一個長期存活的類會快取并丟棄物件參考,則必須注意避免過時參考
4. 使用不可變物件和標準化物件
4.1. 不可變物件為標準化這種特殊的生命周期管理提供了可能性
4.2. 最常見的Java物件是不可變的String物件
4.2.1. 字串可以呼叫intern()方法來找到這個字串的標準化版本
4.3. 物件的標準化版本
4.3.1. canonical version
4.3.2. 不可變物件的單一表示
4.3.3. 通過標準化消除不可變物件的重復副本,可以極大地減少應用程式的堆使用量
4.3.4. 使用標準化的值通常也可以節省記憶體
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/546327.html
標籤:其他
