Java高级进阶学习-Java的内存回收(4)_时空网络_新浪博客
   对于c++程序来说,对象占用的内存空间都必须由程序显式回收,如果程序员忘记了回收它们,那它们所占用的内存空间就会产生内存泄漏;对于java程序来说,所有不可达的对象都由垃圾回收机制负责回收,因此程序员不需要考虑这部分的内存泄漏。但如果程序中有一些java对象,它们处于可达状态,但程序以后永远都不会再访问它们,那它们所占用的空间也不会被回收,它们所占用的空间也会产生内存泄漏.
 例如,如下图中
 有ArrayList的长度是4,有四个元素“网”,“络”,“时”,“空”,当我们删除了ArrayList中的"网"这个元素时,它的size等于3,也就是该ArrayList认为自己只有3个元素,因此它永远也不会去访问底层数组的第4个元素。对于程序本身来说,这个对象已经变成了垃圾,但对于垃圾回收机制来说,这个对象依然处于可达状态,因此不会回收它,这就产生了内存泄漏了








其实解决方法也很简单,程序员显式赋值让 “网”对应的字符串对象 为 null 就行了

 

 再看下面程序采用基于数组的方式实现了一个Stack,大家可以找找这个程序中的内存泄漏
public class Stack
{
 //存放栈内元素的数组
 private Object[] elementData;
 //记录栈内元素的个数
 private int size = 0;
 private int capacityIncrement;
 //以指定初始化容量创建一个Stack
 public Stack(int initialCapacity)
 {
  elementData = new Object[initialCapacity];
 }
 public Stack(int initialCapacity , int capacityIncrement)
 {
  this(initialCapacity);
  this.capacityIncrement = capacityIncrement;
 }
 //向“栈”顶压入一个元素
 public void push(Object object)
 {
  ensureCapacity();
  elementData[size++] = object;
  // if(size==10) System.out.println("size="+size);
 }
 public Object pop()
 {
  if(size == 0)
  {
   throw new RuntimeException("空栈异常");
  }
  return elementData[--size];
 }

 public int size()
 {
  return size;
 }
 //保证底层数组能容纳栈内所有元素
 private void ensureCapacity()
 {
  //增加堆栈的容量
  if(elementData.length==size)
  {
   Object[] oldElements = elementData;
   int newLength = 0;
   //已经设置capacityIncrement
   if (capacityIncrement > 0)
   {
    newLength = elementData.length + capacityIncrement;
   }
   else
   {
    //将长度扩充到原来的1.5倍
    newLength = (int)(elementData.length * 1.5);
   }
   // System.out.println("newLength="+newLength);
   elementData = new Object[newLength];
   //将原数组的元素复制到新数组中
   System.arraycopy(oldElements , 0 , elementData , 0 , size);
  }
 }
 public static void main(String[] args)
 {
  Stack stack = new Stack(10);
  //向栈顶压入10个元素
  for (int i = 0 ; i < 10 ; i++)
  {
   stack.push("元素" + i);
  }
  //依次弹出10个元素
  for (int i = 0 ; i < 10 ; i++)
  {
   System.out.println(stack.pop());
  }
 }
}


  上面程序实现了一个简单的Stack,并为这个Stack实现了push(),pop()两个方法,其中pop()方法可能产生内存泄漏。为了说明这个Stack的内存泄漏,程序main方法创建了一个Stack对象,先向该Stack压入10个元素。注意:此时底层elementData的长度为10,每人数组元素都引用一个字符串。
  接下来,程序10次调用pop()方法弹出栈顶元素。注意pop()方法产生的内存泄漏,它只做了两件事:一是修饰Stack的size属性,也就是记录栈内元素减1,二是返回elementData数组中索引为size-1的元素

  也就是说,每调用pop方法一次,Stack会记录该栈的尺寸减1,但未xxelementData数组的{zh1}一个元素的引用,这样就会产生内存泄漏。类似地,也应该按ArrayList类的源代码改写此处pop()方法的源代码,如下所示
 public Object pop()
 {
  if(size == 0)
  {
   throw new RuntimeException("空栈异常");
  }
  Object obj=elementData[--size];
  //xx{zh1}一个数组元素的引用,避免内存江泄漏
  elementData[size]=null;  
  return obj;  
 }

已投稿到:
郑重声明:资讯 【Java高级进阶学习-Java的内存回收(4)_时空网络_新浪博客】由 发布,版权归原作者及其所在单位,其原创性以及文中陈述文字和内容未经(企业库qiyeku.com)证实,请读者仅作参考,并请自行核实相关内容。若本文有侵犯到您的版权, 请你提供相关证明及申请并与我们联系(qiyeku # qq.com)或【在线投诉】,我们审核后将会尽快处理。
—— 相关资讯 ——