64位指针膨胀 java_Java 程序优化知识笔记
遷移 64 位虛擬機未必性能更好
業務量上升以后,需要使用的內存隨之增加,而在通常 32 位系統上,單個進程占用的最大內存通常是 2GB,且考慮到堆外內存的使用,32 位機器可能無法滿足內存要求,一種常見的應對方式就是換用 64 位服務器。而對于 Java,由于指針膨脹和字節對齊,同一個程序在 64 位虛擬機上占用的內存會多于 32 位虛擬機。開發者換用 64 位虛擬機后,很可能會增加虛擬機的堆大小,而這將導致 Full GC 垃圾回收的時間大大增加,導出堆快照也變得困難。
因此,使用 64 位虛擬機增加內存時,需要特別注意對內存的使用,盡量不要觸發 Full GC 導致長時間停頓。另一種方法是建立 32 位虛擬機的集群來提高性能。
堆外內存溢出
Java 本地方法調用,如調用 C++ 實現的本地模塊、NIO 的 DirectByteBuffer,都會占用大量內存。而在開發中,開發者往往重點關注了堆內存的大小,在內存溢出時也傾向于增加堆內存,而忽視了堆外內存的使用。堆外內存并不會像堆內存一樣不足馬上通知 GC 進行垃圾回收,堆外內存只能等待老年代空間不足進行 Full GC 時順便回收內存,否則堆外內存只能等到空間不足時拋出內存溢出異常,然后請求 GC 進行回收。
因此,配置虛擬機,除考慮常規的堆大小外,優化時還需要考慮 Direct Memory、線程棧、socket 緩沖區、JNI 代碼、虛擬機、GC 占用的內存大小。
外部命令的時間消耗
Java 開發中如果需要執行 shell 腳本,可以使用 Runtime.getRuntime().exec 方法,還能從返回的 Process 對象中讀取標準輸出、錯誤輸出、等待執行結束。根據方法注釋,該方法首先復制當前進程產生一個子進程,在子進程中執行命令,結束后退出子進程。
進程的復制比較消耗 CPU 和內存,應盡量通過 Java 程序本身去完成相關功能。
多線程使用線程池
Java 虛擬機中沒有給用戶用的多進程方法,并行處理更多地使用多線程方式。默認情況下,Linux 限制用戶的線程數量上限為 1024,當然包括了系統中運行的所有線程。通常情況下,線程資源不會被耗盡,但多線程程序如果頻繁創建新線程也會遇到線程資源不足的情況。一方面,可以調整系統設置,提高線程數上限,另一方面,應盡量避免頻繁創建線程。線程雖小,創建時一樣要消耗時間和內存。
多線程程序應盡量采用 Java 的線程池,這樣線程的個數總體可控,使用時可以避免創建線程的時間消耗。Java 提供了多種功能強大的線程池類型,基于線程池可以對任務進行緩存、按照一定的時間頻率執行任務、返回執行結果、分叉與合并等。
每周 3 篇學習筆記或技術總結,面向有一定基礎的 Java 程序員,內容涉及 Java 進階、虛擬機、MySQL、NoSQL、分布式計算、開源框架等多個領域。關注作者或微信公眾號 backend-develop 第一時間獲取最新內容。
《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀總結
以上是生活随笔為你收集整理的64位指针膨胀 java_Java 程序优化知识笔记的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: pe工具箱怎么装系统 使用pe工具箱安装
- 下一篇: 买房子为什么不能选7楼?