java內存區域/內存溢出匯總
本文主要介紹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) 內存泄露可以通過完善代碼來避免;內存溢出可以通過調整配置來減少發生頻率,但無法徹底避免。
虛擬機棧
存放基本數據類型,對象引用,操作數棧,動態鏈接,方法出口
異常原因:
(StackoverflowError)線程請求的棧深度大於虛擬結所允許的最大深度(eg:遞歸沒有跳出)
(OutOfMemoryError)在擴展棧時無法申請到足夠的內存空間
異常處理:
1.檢查是否有遞歸沒有正常結束代碼
2.適當調整棧內存大小-Xss
程序計數器
當前線程所執行的字節碼的行號指示器。(控制代碼的執行順序)
是一塊較小的內存空間,沒有規定任何OutOfMemoryError
本地方法棧
和虛擬機方法棧類似,只是負責Native方法
HotSpot將此棧與虛擬機棧合二為一。
異常同虛擬機棧異常。
-Xoss修改本地方法棧內存(但HotSpot此參數無效,通過設置-Xss來修改)
本機直接內存
不是虛擬機規範中的內存區域。NIO等一些處理直接使用的內存,可以使用Native函數庫直接分配堆外內存,避免Java堆和Native堆中的來回復制數據,
異常現象:
在出現OutOfMemoryError後,Heap Dump 文件中,沒有明顯的異常,如果程序中又直接或間接的使用的NIO,就可以考慮檢查是不是此內存溢出。
異常處理:
-XX:MaxDirectMemorySize
java內存區域/內存溢出匯總