欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

淺談Java編程中的內(nèi)存泄露情況

 更新時間:2015年10月21日 08:58:23   作者:wade6  
這篇文章主要介紹了Java編程中的內(nèi)存泄露情況,牽扯到JVM的垃圾回收相關(guān)知識,需要的朋友可以參考下

必須先要了解的
1。c/c++是程序員自己管理內(nèi)存,Java內(nèi)存是由GC自動回收的。
我雖然不是很熟悉C++,不過這個應該沒有犯常識性錯誤吧。
2。什么是內(nèi)存泄露?
內(nèi)存泄露是指系統(tǒng)中存在無法回收的內(nèi)存,有時候會造成內(nèi)存不足或系統(tǒng)崩潰。
在C/C++中分配了內(nèi)存不釋放的情況就是內(nèi)存泄露。
3。Java存在內(nèi)存泄露
我們必須先承認這個,才可以接著討論。雖然Java存在內(nèi)存泄露,但是基本上不用很關(guān)心它,特別是那些對代碼本身就不講究的就更不要去關(guān)心這個了。
Java中的內(nèi)存泄露當然是指:存在無用但是垃圾回收器無法回收的對象。
而且即使有內(nèi)存泄露問題存在,也不一定會表現(xiàn)出來。
4。Java中參數(shù)都是傳值的。
對于基本類型,大家基本上沒有異議,但是對于引用類型我們也不能有異議。
 

Java內(nèi)存泄露情況
 
1、堆內(nèi)存溢出(outOfMemoryError:java heap space)
       在jvm規(guī)范中,堆中的內(nèi)存是用來生成對象實例和數(shù)組的。
       如果細分,堆內(nèi)存還可以分為年輕代和年老代,年輕代包括一個eden區(qū)和兩個survivor區(qū)。
       當生成新對象時,內(nèi)存的申請過程如下:
          a、jvm先嘗試在eden區(qū)分配新建對象所需的內(nèi)存;
          b、如果內(nèi)存大小足夠,申請結(jié)束,否則下一步;
          c、jvm啟動youngGC,試圖將eden區(qū)中不活躍的對象釋放掉,釋放后若Eden空間仍然不足以放入新對象,則試圖將部分Eden中活躍對象放入Survivor區(qū);
          d、Survivor區(qū)被用來作為Eden及old的中間交換區(qū)域,當OLD區(qū)空間足夠時,Survivor區(qū)的對象會被移到Old區(qū),否則會被保留在Survivor區(qū);
          e、 當OLD區(qū)空間不夠時,JVM會在OLD區(qū)進行full GC;
          f、full GC后,若Survivor及OLD區(qū)仍然無法存放從Eden復制過來的部分對象,導致JVM無法在Eden區(qū)為新對象創(chuàng)建內(nèi)存區(qū)域,則出現(xiàn)”out of memory錯誤”:
                                 

 outOfMemoryError:java heap space

2、方法區(qū)內(nèi)存溢出(outOfMemoryError:permgem space)
       在jvm規(guī)范中,方法區(qū)主要存放的是類信息、常量、靜態(tài)變量等。
       所以如果程序加載的類過多,或者使用反射、gclib等這種動態(tài)代理生成類的技術(shù),就可能導致該區(qū)發(fā)生內(nèi)存溢出,一般該區(qū)發(fā)生內(nèi)存溢出時的錯誤信息為:

       outOfMemoryError:permgem space

3、線程棧溢出(java。lang。StackOverflowError)
       線程棧時線程獨有的一塊內(nèi)存結(jié)構(gòu),所以線程棧發(fā)生問題必定是某個線程運行時產(chǎn)生的錯誤。
       一般線程棧溢出是由于遞歸太深或方法調(diào)用層級過多導致的。
       發(fā)生棧溢出的錯誤信息為:

       java。lang。StackOverflowError

內(nèi)存泄露的幾種場景:
 
1、長生命周期的對象持有短生命周期對象的引用
 
            這是內(nèi)存泄露最常見的場景,也是代碼設計中經(jīng)常出現(xiàn)的問題。
            例如:在全局靜態(tài)map中緩存局部變量,且沒有清空操作,隨著時間的推移,這個map會越來越大,造成內(nèi)存泄露。
 
2、修改hashset中對象的參數(shù)值,且參數(shù)是計算哈希值的字段
 
             當一個對象被存儲進HashSet集合中以后,就不能修改這個對象中的那些參與計算哈希值的字段,否則對象修改后的哈希值與最初存儲進HashSet集合中時的哈希值就不同了,在這種情況下,即使在contains方法使用該對象的當前引用作為參數(shù)去HashSet集合中檢索對象,也將返回找不到對象的結(jié)果,這也會導致無法從HashSet集合中刪除當前對象,造成內(nèi)存泄露。
 
3、機器的連接數(shù)和關(guān)閉時間設置
 
            長時間開啟非常耗費資源的連接,也會造成內(nèi)存泄露。


 
來看個內(nèi)存泄露的例子:

public class Stack {
 private Object[] elements=new Object[10];
 private int size = 0;
 
 public void push(Object e){
 ensureCapacity();
 elements[size++] = e; 
 }
 
 public Object pop(){
 if( size == 0) 
  throw new EmptyStackException(); 
 return elements[--size];
 }
 
 private void ensureCapacity(){
 if(elements。length == size){
  Object[] oldElements = elements;
  elements = new Object[2 * elements。length+1];
  System。arraycopy(oldElements,0, elements, 0, size);
 }
 }
}

上面的原理應該很簡單,假如堆棧加了10個元素,然后全部彈出來,雖然堆棧
是空的,沒有我們要的東西,但是這是個對象是無法回收的,這個才符合了內(nèi)存
泄露的兩個條件:無用,無法回收。
 

但是就是存在這樣的東西也不一定會導致什么樣的后果,如果這個堆棧用的比較少,
也就浪費了幾個K內(nèi)存而已,反正我們的內(nèi)存都上G了,哪里會有什么影響,再說
這個東西很快就會被回收的,有什么關(guān)系。下面看兩個例子。
 
例子1

public class Bad{
  public static Stack s=Stack();
  static{
    s。push(new Object());
    s。pop(); //這里有一個對象發(fā)生內(nèi)存泄露
    s。push(new Object()); //上面的對象可以被回收了,等于是自愈了
  }
}


因為是static,就一直存在到程序退出,但是我們也可以看到它有自愈功能,
就是說如果你的Stack最多有100個對象,那么最多也就只有100個對象無法被回收
其實這個應該很容易理解,Stack內(nèi)部持有100個引用,最壞的情況就是他們都是
無用的,因為我們一旦放新的進取,以前的引用自然消失!
 
例子2

public class NotTooBad{
  public void doSomething(){
    Stack s=new Stack();
    s。push(new Object());
    //other code
    s。pop();//這里同樣導致對象無法回收,內(nèi)存泄露。
  }//退出方法,s自動無效,s可以被回收,Stack內(nèi)部的引用自然沒了,所以
   //這里也可以自愈,而且可以說這個方法不存在內(nèi)存泄露問題,不過是晚一點
   //交給GC而已,因為它是封閉的,對外不開放,可以說上面的代碼99。9999%的
   //情況是不會造成任何影響的,當然你寫這樣的代碼不會有什么壞的影響,但是
   //絕對可以說是垃圾代碼!沒有矛盾吧,我在里面加一個空的for循環(huán)也不會有
   //什么太大的影響吧,你會這么做嗎?
}

 
上面兩個例子都不過是小打小鬧,但是C/C++中的內(nèi)存泄露就不是Bad了,而是Worst了。
他們?nèi)绻惶帥]有回收就永遠無法回收,頻繁的調(diào)用這個方法內(nèi)存不就用光了!
因為Java還有自愈功能(我自己起的名字,還沒申請專利),所以Java的內(nèi)存泄露問題
幾乎可以忽略了,但是知道的人就不要犯了。

為了避免內(nèi)存泄露,在編寫代碼的過程中可以參考下面的建議:
 
1、盡早釋放無用對象的引用;
 
2、使用字符串處理,避免使用String,應大量使用StringBuffer,每一個String對象都得獨立占用內(nèi)存一塊區(qū)域;
 
3、盡量少用靜態(tài)變量,因為靜態(tài)變量存放在永久代(方法區(qū)),永久代基本不參與垃圾回收;
 
4、避免在循環(huán)中創(chuàng)建對象;
 
5、開啟大型文件或從數(shù)據(jù)庫一次拿了太多的數(shù)據(jù)很容易造成內(nèi)存溢出,所以在這些地方要大概計算一下數(shù)據(jù)量的最大值是多少,并且設定所需最小及最大的內(nèi)存空間值。

相關(guān)文章

  • java字符串格式化(String類format方法)

    java字符串格式化(String類format方法)

    這篇文章主要介紹了java字符串格式化(String類format方法),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-02-02
  • Java幾種常用JSON庫性能比較詳解

    Java幾種常用JSON庫性能比較詳解

    這篇文章主要介紹了Java幾種常用JSON庫性能比較詳解,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2019-06-06
  • SpringBoot參數(shù)校驗之@Validated的使用詳解

    SpringBoot參數(shù)校驗之@Validated的使用詳解

    這篇文章主要通過示例為大家詳細介紹一下介紹了SpringBoot參數(shù)校驗中@Validated的使用方法,文中的示例代碼講解詳細,需要的可以參考一下
    2022-06-06
  • 詳解Springboot快速搭建跨域API接口的步驟(idea社區(qū)版2023.1.4+apache-maven-3.9.3-bin)

    詳解Springboot快速搭建跨域API接口的步驟(idea社區(qū)版2023.1.4+apache-maven-3.9.

    這篇文章主要介紹了Springboot快速搭建跨域API接口(idea社區(qū)版2023.1.4+apache-maven-3.9.3-bin),本文通過圖文并茂的形式給大家介紹的非常詳細,需要的朋友可以參考下
    2023-07-07
  • Java Web Listener實現(xiàn)事件監(jiān)聽與處理

    Java Web Listener實現(xiàn)事件監(jiān)聽與處理

    Java Web開發(fā)中的Listener是一種事件機制,通過監(jiān)聽Web應用程序的事件,實現(xiàn)對事件的處理,從而實現(xiàn)更加靈活和高效的應用程序開發(fā)。Listener能夠監(jiān)聽的事件包括應用程序啟動和關(guān)閉、Session創(chuàng)建和銷毀、請求和響應對象的創(chuàng)建和銷毀等
    2023-04-04
  • Java函數(shù)式編程(七):MapReduce

    Java函數(shù)式編程(七):MapReduce

    這篇文章主要介紹了Java函數(shù)式編程(七):MapReduce,本文是系列文章的第7篇,其它文章請參閱本文底部的相關(guān)文章,需要的朋友可以參考下
    2014-09-09
  • Java代碼統(tǒng)計網(wǎng)站中不同省份用戶的訪問數(shù)

    Java代碼統(tǒng)計網(wǎng)站中不同省份用戶的訪問數(shù)

    這篇文章主要介紹了Java代碼統(tǒng)計網(wǎng)站中不同省份用戶的訪問數(shù) 的相關(guān)資料,非常具有參考借鑒價值,感興趣的朋友一起學習吧
    2016-05-05
  • Java中Optional的使用指南

    Java中Optional的使用指南

    這篇文章主要給大家介紹了關(guān)于Java中Optional使用的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-01-01
  • java多態(tài)中的就近原則介紹

    java多態(tài)中的就近原則介紹

    大家好,本篇文章主要講的是java多態(tài)中的就近原則介紹,感興趣的同學趕快來看一看吧,對你有幫助的話記得收藏一下,方便下次瀏覽
    2021-12-12
  • java jdbc連接和使用詳細介紹

    java jdbc連接和使用詳細介紹

    這篇文章主要介紹了 java jdbc連接和使用詳細介紹的相關(guān)資料,需要的朋友可以參考下
    2016-12-12

最新評論