1. 程式人生 > >Java_記憶體溢位(Memory Overflow)和記憶體洩露(Memory Leak)的區別

Java_記憶體溢位(Memory Overflow)和記憶體洩露(Memory Leak)的區別

via: http://www.cnblogs.com/fryy/archive/2013/11/27/3445281.html

記憶體洩漏指你用malloc或new申請了一塊記憶體,但是沒有通過free或delete將記憶體釋放,導致這塊記憶體一直處於佔用狀態
記憶體溢位指你申請了10個位元組的空間,但是你在這個空間寫入11或以上位元組的資料,就是溢位

要點

  • 記憶體洩露是指程式中間動態分配了記憶體,但在程式結束時沒有釋放這部分記憶體,從而造成那部分記憶體不可用的情況,重啟計算機可以解決,但也有可能再次發生記憶體洩露,記憶體洩露和硬體沒有關係,它是由軟體設計缺陷引起的。 
  • 記憶體洩漏可以分為4類:

    1)常發性記憶體洩漏。發生記憶體洩漏的程式碼會被多次執行到,每次被執行的時候都會導致一塊記憶體洩漏。

    2)偶發性記憶體洩漏。發生記憶體洩漏的程式碼只有在某些特定環境或操作過程下才會發生。常發性和偶發性是相對的。對於特定的環境,偶發性的也許就變成了常發性的。所以測試環境和測試方法對檢測記憶體洩漏至關重要。

    3)一次性記憶體洩漏。發生記憶體洩漏的程式碼只會被執行一次,或者由於演算法上的缺陷,導致總會有一塊僅且一塊記憶體發生洩漏。比如,在類的建構函式中分配記憶體,在解構函式中卻沒有釋放該記憶體,所以記憶體洩漏只會發生一次。

    4)隱式記憶體洩漏。程式在執行過程中不停的分配記憶體,但是直到結束的時候才釋放記憶體。嚴格的說這裡並沒有發生記憶體洩漏,因為最終程式釋放了所有申請的記憶體。但是對於一個伺服器程式,需要執行幾天,幾周甚至幾個月,不及時釋放記憶體也可能導致最終耗盡系統的所有記憶體。所以,我們稱這類記憶體洩漏為隱式記憶體洩漏。

  • 記憶體溢位即使用者在對其資料緩衝區操作時,超過了其緩衝區的邊界;尤其是對緩衝區寫操作時,緩衝區的溢位很可能導致程式的異常。
  • 記憶體溢位型別:

    1)java.lang.OutOfMemoryError:PermGen space

    PermGen space 的全稱是 Permanent Generation space,是指記憶體的永久儲存區域。這塊記憶體主要是被JVM存放Class和Meta資訊的,Class在被Loader時就會被放到PermGenspace中,它和存放類例項(Instance)的Heap區域不同,GC不會在主程式執行期對PermGenspace進行清理。

    JVM由XX:PermSize設定非堆記憶體初始值,預設是實體記憶體的1/64;

    JVM由XX:MaxPermSize設定最大非堆記憶體的大小,預設是實體記憶體的1/4。

    該錯誤常見場合:

    a) 應用中有很多Class,web伺服器對JSP進行pre compile時。

    b) Webapp下用了大量的第三方jar, 其大小超過了JVM預設的大小(4M)時。

    2)java.lang.OutOfMemoryError:Java heap space

    在JVM中如果98%的時間是用於GC且可用的Heap size 不足2%的時候將丟擲此異常資訊。

    JVM初始分配的記憶體由-Xms指定,預設是實體記憶體的1/64; 

    JVM最大分配的記憶體由-Xmx指定,預設是實體記憶體的1/4。 

    JVM記憶體的最大值跟作業系統有很大的關係。32位處理器雖然可控記憶體空間有4GB,但是具體的作業系統會給一個限制,這個限制一般是2GB-3GB(一般來說Windows系統下為1.5G-2G,Linux系統下為2G-3G),而64bit以上的處理器就不會有限制了。

    注意:如果Xms超過了Xmx值,或者堆最大值和非堆最大值的總和超過了實體記憶體或者作業系統的最大限制都會引起伺服器啟動不起來。 

    該錯誤常見場合:

    a) Web上傳檔案時。

    b) 開啟大型檔案或從資料庫中一次取了太多的資料。 
     

相關問題

1. Q:Java中會存在記憶體洩漏嗎?
   
A: Java中也存在記憶體洩露。當被分配的物件可達但已無用(未對作廢資料記憶體單元的引用置null)即會引起。 如:

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: 同:都會導致應用程式執行出現問題,效能下降或掛起。

        異:

        1) 記憶體洩露是導致記憶體溢位的原因之一;記憶體洩露積累起來將導致記憶體溢位。

        2) 記憶體洩露可以通過完善程式碼來避免;記憶體溢位可以通過調整配置來減少發生頻率,但無法徹底避免。

3. 如何檢測記憶體洩露?   

 A: 可以通過一些效能監測分析工具,如 JProfiler、OptimizeitProfiler。

4. Q: 如何避免記憶體洩露、溢位?

A: 1)儘早釋放無用物件的引用。

          好的辦法是使用臨時變數的時候,讓引用變數在退出活動域後自動設定為null,暗示垃圾收集器來收集該物件,防止發生記憶體洩露。

         2)程式進行字串處理時,儘量避免使用String,而應使用StringBuffer。

          因為每一個String物件都會獨立佔用記憶體一塊區域,如:

String str = "aaa";   
String str2 = "bbb";   
String str3 = str  str2;   
// 假如執行此次之後str , str2再不被呼叫,那麼它們就會在記憶體中等待GC回收;   
// 假如程式中存在過多的類似情況就會出現記憶體錯誤;

        3) 儘量少用靜態變數。

         因為靜態變數是全域性的,GC不會回收。

         4)避免集中建立物件尤其是大物件,如果可以的話儘量使用流操作。

        JVM會突然需要大量記憶體,這時會觸發GC優化系統記憶體環境; 一個案例如下: 

  1. // 使用jspsmartUpload作檔案上傳,執行過程中經常出現java.outofMemoryError的錯誤,   
  2. // 檢查之後發現問題:元件裡的程式碼   
  3. m_totalBytes = m_request.getContentLength();   
  4. m_binArray = new byte[m_totalBytes];   
  5. // totalBytes這個變數得到的數極大,導致該陣列分配了很多記憶體空間,而且該陣列不能及時釋放。   
  6. // 解決辦法只能換一種更合適的辦法,至少是不會引發outofMemoryError的方式解決。   
  7. // 參考:http://bbs.xml.org.cn/blog/more.asp?name=hongrui&id=3747   

        5)儘量運用物件池技術以提高系統性能。

         生命週期長的物件擁有生命週期短的物件時容易引發記憶體洩漏,例如大集合物件擁有大資料量的業務物件的時候,可以考慮分塊進行處理,然後解決一塊釋放一塊的策略。

         6)不要在經常呼叫的方法中建立物件,尤其是忌諱在迴圈中建立物件。

         可以適當的使用hashtable,vector建立一組物件容器,然後從容器中去取那些物件,而不用每次new之後又丟棄。

        7) 優化配置。

5. Q:記憶體溢位的解決方案? 
    
A: 一是從程式碼層面進行優化完善,儘量避免該情況發生;

        二是調整優化伺服器配置: 

        1) 設定-Xms、-Xmx相等;

        2) 設定NewSize、MaxNewSize相等;

        3) 設定Heap size, PermGen space:

            Tomcat 的配置示例:修改 %TOMCAT_HOME%/bin/catalina.bat or catalina.sh

            在“echo "Using CATALINA_BASE: $CATALINA_BASE"”上面加入以下行:

     set JAVA_OPTS=-Xms800m -Xmx800m -XX:PermSize=128M -XX:MaxNewSize=256m -XX:MaxPermSize=256m


相關推薦

Java_記憶體溢位(Memory Overflow)記憶體洩露(Memory Leak)的區別

via: http://www.cnblogs.com/fryy/archive/2013/11/27/3445281.html 記憶體洩漏指你用malloc或new申請了一塊記憶體,但是沒有通過free或delete將記憶體釋放,導致這塊記憶體一直處於佔用狀態 記憶

DDMS的使用、記憶體溢位的除錯模擬器的啟動命令引數

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

Java多執行緒程式設計-(11)-面試常客ThreadLocal出現OOM記憶體溢位的場景原理分析

一、案例程式碼 1、首先看一下程式碼,模擬了一個執行緒數為500的執行緒池,所有執行緒共享一個ThreadLocal變數,每一個執行緒執行的時候插入一個大的List集合: 2、設定JVM引數設定最大記憶體為256M,以便模擬出OOM: 3、執行程式碼,輸出結果: 可以看出,單執行緒池

Java服務記憶體溢位問題解決總結

最近,公司測試環境服務發現一個問題:一個介面服務,合作方再調介面時,經常會出現連線超時異常(connection reset by peer),緊接著看到服務記憶體100%,加記憶體也沒用,不管加多少還是會緩慢升至100%。如下圖: 通過各位大神的指點迷津,大概定位到以

java -excel-讀取較大的excel檔案防止記憶體溢位(相容Excel20032007)

如果覺得寫得可以 或者太差 就 評論一下或者贊一下唄,多謝支援!!1. 需要的jar<!-- https://mvnrepository.com/artifact/org.apache.poi/poi excle 檔案 --><dependency> 

【JVM】記憶體區域分配機制記憶體溢位異常

前言:    對於Java和C類語言來說,它們二者之間存在一個很大的區別:記憶體動態分配和垃圾回收機制(GC)。對於C 或C++來說,它們的記憶體管理是有開發人員決定的,也就是收一個物件的生存週期各

記憶體(RAM或ROM)FLASH儲存的真正區別總結

1.什麼是記憶體      什麼是記憶體呢?在計算機的組成結構中,有一個很重要的部分,就是儲存器。儲存器是用來儲存程式和資料的部件,對於計算機來說,有了儲存器,才有記憶功能,才能保證正常工作。儲存器的種類很多,按其用途可分為主儲存器和輔助儲存器,主儲存器又稱記憶體儲器(簡稱

記憶體溢位時,儲存記憶體快照:-XX:+HeapDumpOnOutOfMemoryError

-XX:+HeapDumpOnOutOfMemoryError該配置會把快照儲存在使用者目錄或者tomcat目錄下,也可以通過 -XX:HeapDumpPath=/tmp/heapdump.hprof 來顯示指定路徑此外,OnOutOfMemoryError引數允許使用者指定

myeclipse啟動tomcat記憶體溢位,或tomcat記憶體溢位問題解決辦法

        最近專案開發中老是遇到啟動專案後報記憶體溢位,首先我們要確定問題所在,MyEclipse啟動Tomcat無視catalina.bat中設定記憶體大小,所以說如果用myeclipse啟動tomcat記憶體溢位,而tomcat直接啟動不報錯的話,一定是MyEcl

記憶體洩露記憶體溢位區別 (概念區別 產生原因區別 及解決辦法) 個人整理

記憶體洩露和記憶體溢位的區別 概念區別 記憶體溢位 : out of memory 指程式在申請記憶體時,沒有足夠的記憶體空間供其使用,出現out fo memory 比如申請一個integer 但給它存了long才能存下的數那就是記憶體溢位 記憶體洩露 : memory leak 指程

記憶體洩露 記憶體溢位

記憶體溢位 out of memory,是指程式在申請記憶體時,沒有足夠的記憶體空間供其使用,出現out of memory; 記憶體洩漏(Memory Leak)是指程式中己動態分配的堆記憶體由於某種原因程式未釋放或無法釋放,造成系統記憶體的浪費,導致程式執行速度減慢甚至系統崩潰等嚴重後果。

Java虛擬機器7:記憶體溢位記憶體洩露、並行併發、Minor GCFull GC、Client模式Server模式的區別

記憶體溢位和記憶體洩露的區別 1、記憶體溢位 記憶體溢位指的是程式在申請記憶體的時候,沒有足夠大的空間可以分配了。 2、記憶體洩露 記憶體洩露指的是程式在申請記憶體之後,沒有辦法釋放掉已經申請到記憶體,它始終佔用著記憶體,即被分配的物件可達但無用。記憶體洩露一般都是因

堆(heap)棧(stack)、記憶體洩漏(memory leak)記憶體溢位

簡單的可以理解為: heap:是由malloc之類函式分配的空間所在地。地址是由低向高增長的。 stack:是自動分配變數,以及函式呼叫的時候所使用的一些空間。地址是由高向低減少的。 一、預備知識—程式的記憶體分配 一個由c/C++編譯的程式佔用的記憶體分為以下幾個部分

記憶體洩露記憶體溢位區別

· 記憶體洩露是指程式中間動態分配了記憶體,但在程式結束時沒有釋放這部分記憶體,從而造成那部分記憶體不可用的情況,重啟計算機可以解決,但也有可能再次發生記憶體洩露,記憶體洩露和硬體沒有關係,它是由軟體設計缺陷引起的。  · 記憶體洩漏可以分為4類:  1) 常發性記憶體洩漏。發生記憶體洩漏的程式碼會被多次執

java記憶體溢位溢位例項以及記憶體溢位記憶體洩露區別

記憶體溢位和記憶體洩露的區別:記憶體溢位 out of memory,是指程式在申請記憶體時,沒有足夠的記憶體空間供其使用,出現out of memory;比如申請了一個integer,但給它存了lo

記憶體溢位洩露

一、記憶體溢位和記憶體洩露 一種通俗的說法。1、記憶體溢位:你申請了10個位元組的空間,但是你在這個空間寫入11或以上位元組的資料,出現溢位。2、記憶體洩漏:你用new申請了一塊記憶體,後來很長時間都不再使用了(按理應該釋放),但是因為一直被某個或某些例項所持有導致 GC 不能回收,也就是該被釋放的物件沒有

c語言-記憶體洩露記憶體溢位區別

記憶體溢位     指你申請了10個位元組的空間,但是你在這個空間寫入11或以上位元組的資料,就是溢位 記憶體洩漏     指你用malloc或new申請了一塊記憶體,但是沒有通過free或delete將記憶體釋放,導致這塊記憶體一直處於佔用狀態。 #includ

深入理解記憶體溢位洩露

上週考試見老師給同學們出的一道題:什麼是記憶體洩露,舉例說明。很有趣的是聽改卷的老師說,前面有一道遞迴題,然後有部分同學直接去掉了遞迴的出口,把他作為記憶體洩露的例子。 這一點讓我意識到很多人其實並沒有分清楚記憶體洩露和記憶體溢位,那麼說根本就是沒懂記憶體洩露和記憶體

Android面試準備:記憶體洩露記憶體溢位

概念 記憶體洩露:申請的記憶體沒有及時釋放掉,這樣的話就會造成程式能使用的記憶體資源越來越少,最終會導致系統無法再提供記憶體資源; 譬如說,一個map裡面一直在新增新的物件,這樣的話就很有可能造成記憶體洩露。 記憶體溢位:就是要求分配的記憶體超出了系統提供

記憶體洩漏(memory leak記憶體溢位(out of memory

一、概念: memory leak---記憶體洩漏:是指程式申請記憶體空間後,無法釋放。然而,記憶體洩漏不斷疊加會導致系統把記憶體花完,以致於發生記憶體溢位。(用了不還) out of memory-