二、Java内存泄露
  对于c++程序来说,对象占用的内存空间都必须由程序显式回收,如果程序员忘记了回收它们,那它们所占用的内存空间会产生内存泄漏;对于java程序来说,所有不可达的对象都由垃圾回收机制负责回收,因此程序员不需要考虑这部分的内存泄漏。但如果程序中有一些java对象,它们处于可达状态,但程序以后永远都不会再访问它们,那它们所占用的空间也不会被回收,它们所占用的空间也会产生内存泄漏.
  例如:
  有ArrayList的长度是4,有四个元素“网”,“络”,“时”,“空”,当我们删除了ArrayList中的"网"这个元素时,它的size等于3,也是该ArrayList认为自己只有3个元素,因此它永远也不会去访问底层数组的第4个元素。对于程序本身来说,这个对象已经变成了垃圾,但对于垃圾回收机制来说,这个对象依然处于可达状态,因此不会回收它,这产生了内存泄漏了
  再看下面程序采用基于数组的方式实现了一个Stack,大家可以找找这个程序中的内存泄漏
package list;
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());
}
}
}