標籤:mem dir 指示 java strong intern 分配 串處理 方法區
本文主要介紹Java虛擬機器中的記憶體地區與各種記憶體溢出情況匯總。
資料區域
方法區、堆、虛擬機器棧、程式計數器、本地方法棧
方法區
用於儲存已被虛擬機器載入的類資訊、常量、靜態變數、即時編譯器編譯後的代碼
運行時常量池:存放編譯期產生的字面量和符號引用
異常(OutofMemoryError: PermGen space)產生原因:
1.往常量池中添加大量資料。eg:String.intern()
2.大量的類資訊(或者動態代理)
異常處理:
適當增大配置:-XX:PermSize -XX:MaxPermSize
堆
存放對象執行個體
異常(OutofMemoryError)產生原因:
1.記憶體流失,最後導致記憶體溢出
2.代碼建立過多個物件導致超過設定的記憶體大小
異常處理(參考:http://blog.csdn.net/wisgood/article/details/16818243)
1.儘早釋放無用對象的引用(好的辦法是使用臨時變數的時候,讓引用變數在退出活動域後自動化佈建為null,暗示垃圾收集器來收集該對象,防止發生記憶體泄露。)
2.程式進行字串處理時,盡量避免使用String,而應使用StringBuffer(因為每一個String對象都會獨立佔用記憶體一塊地區)
3.盡量少用靜態變數(因為靜態變數是全域的,GC不會回收)
4.避免集中建立對象尤其是大對象,如果可以的話盡量使用流操作
5. 盡量運用對象池技術以提高系統效能
6.不要在經常調用的方法中建立對象,尤其是忌諱在迴圈中建立對象
7.最佳化配置:-Xms -Xmx
1. Q: Java中會存在記憶體流失嗎? A: Java中也存在記憶體泄露。當被分配的對象可達但已無用(未對作廢資料記憶體單元的引用置null)即會引起。 如:Java代碼Vector v=new Vector(10); for (int i=1;i<100; i ) { Object o=new Object(); v.add(o); o=null; } // 此時,所有的Object對象都沒有被釋放,因為變數v引用這些對象。 // 對象加入到Vector後,還必須從Vector中刪除,最簡單釋放方法就是將Vector對象設定為null。 2. Q: 記憶體泄露、溢出的異同? A: 同:都會導致應用程式運行出現問題,效能下降或掛起。 B: 異: 1) 記憶體泄露是導致記憶體溢出的原因之一;記憶體泄露積累起來將導致記憶體溢出。 2) 記憶體泄露可以通過完善代碼來避免;記憶體溢出可以通過調整配置來減少發生頻率,但無法徹底避免。
虛擬機器棧
存放基礎資料型別 (Elementary Data Type),對象引用,運算元棧,動態連結,方法出口
異常原因:
(StackoverflowError)線程請求的棧深度大於虛擬結所允許的最大深度(eg:遞迴沒有跳出)
(OutOfMemoryError)在擴充棧時無法申請到足夠的記憶體空間
異常處理:
1.檢查是否有遞迴沒有正常結束代碼
2.適當調整棧記憶體大小-Xss
程式計數器
當前線程所執行的位元組碼的行號指標。(控制碼的執行順序)
是一塊較小的記憶體空間,沒有規定任何OutOfMemoryError
本地方法棧
和虛擬機器方法棧類似,只是負責Native方法
HotSpot將此棧與虛擬機器棧合二為一。
異常同虛擬機器棧異常。
-Xoss修改本地方法棧記憶體(但HotSpot此參數無效,通過設定-Xss來修改)
本機直接記憶體
不是虛擬機器規範中的記憶體地區。NIO等一些處理直接使用的記憶體,可以使用Native函數庫直接分配堆外記憶體,避免Java堆和Native堆中的來回複製資料,
異常現象:
在出現OutOfMemoryError後,Heap Dump 檔案中,沒有明顯的異常,如果程式中又直接或間接的使用的NIO,就可以考慮檢查是不是此記憶體溢出。
異常處理:
-XX:MaxDirectMemorySize
java記憶體地區/記憶體溢出匯總