程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> JAVA編程入門知識 >> Java內存洩露問題分析

Java內存洩露問題分析

編輯:JAVA編程入門知識

  很多人在談論內存洩露問題,當然對於c/c++來說,這個應該是老掉牙的問題,但是很多Java人員也越來越多得討論這個問題,我這裡寫個小結,希望對大家有一定的參考價值。

  內存洩漏的慨念

  1.c/c++是程序員自己管理內存,Java內存是由GC自動回收的。

  我雖然不是很熟悉C++,不過這個應該沒有犯常識性錯誤吧。

  2.什麼是內存洩露?

  內存洩露是指系統中存在無法回收的內存,有時候會造成內存不足或系統崩潰。

  在C/C++中分配了內存不釋放的情況就是內存洩露。

  3.Java存在內存洩露

  我們必須先承認這個,才可以接著討論。雖然Java存在內存洩露,但是基本上不用很關心它,特別是那些對代碼本身就不講究的就更不要去關心這個了。

  Java中的內存洩露當然是指:存在無用但是垃圾回收器無法回收的對象。而且即使有內存洩露問題存在,也不一定會表現出來。

  4.Java中參數都是傳值的。

  對於基本類型,大家基本上沒有異議,但是對於引用類型我們也不能有異議。

  Java內存洩露情況

  JVM回收算法是很復雜的,我也不知道他們怎麼實現的,但是我只知道他們要實現的就是:對於沒有被引用的對象是可以回收的。所以你要造成內存洩露就要做到:

  持有對無用對象的引用!

  不要以為這個很容易做到,既然無用,你怎麼還會持有它的引用? 既然你還持有它,它怎麼會是無用的呢?

  我實在想不到比那個堆棧更經典的例子了,以致於我還要引用別人的例子,下面的例子不是我想到的,是書上看到的,當然如果沒有在書上看到,可能過一段時間我自己也想的到,可是那時我說是我自己想到的也沒有人相信的。

  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個元素,然後全部彈出來,雖然堆棧是空的,沒有我們要的東西,但是這是個對象是無法回收的,這個才符合了內存洩露的兩個條件:無用,無法回收。

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

  例子1

  public class Bad{
  public static Stack s=Stack();
  static{
   s.push(new Object());
   s.pop(); //這裡有一個對象發生內存洩露
   s.push(new Object()); //上面的對象可以被回收了,等於是自愈了
  }
  }

  • 首頁
  • 上一頁
  • 1
  • 2
  • 下一頁
  • 尾頁
  • 共2頁
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved