1. 程式人生 > >java內存區域/內存溢出匯總

java內存區域/內存溢出匯總

.net lower 引用 介紹 全局 防止 異常處理 簡單 href

本文主要介紹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內存區域/內存溢出匯總