很多人都觉着,java有GC,会帮我们自动回收内存,因此java中不存在内存泄露的问题,实际上,这仅仅是一种美好的愿望?
举个例子,比如我们打开一个文件,如果你忘记关了,然后我们打开了许许多多这样的文件,是不是就会造成内存泄露,那这是为什么呢?
我理解就是,java打开文件,实际要调用C,C又调用Windows的API打开文件,我们知道C是需要手动回收内存的,所以,如果我们只打开不关闭,时间长了,自然就会出问题,内存泄露就不可避免了。
另外,我们自己在写代码的时候,如果不及时回收清空对象,也很容易产生内存泄露。比如下面自己定义的一个栈:
/*
* 使用数组方式实现一个Stack
* 关键在pop方法,避免内存泄露
*/
public class MyStack {
//存放栈内元素的数组
private Object[] elementData;
//记录栈内元素的个数
private int size = 0;
//自动增加的速度
private int capacityIncrement;
public MyStack(int initialCapacity){
elementData = new Object[initialCapacity];
}
public MyStack(int initialCapacity , int capacityIncrement){
this(initialCapacity);
this.capacityIncrement = capacityIncrement;
}
//向“栈”顶压入一个元素
public void push(Object object){
ensureCapacity();
elementData[size++] = object;
}
//推出栈顶元素
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[] oldElemnts = elementData;
int newLength = 0;
if(capacityIncrement > 0){
newLength = elementData.length + capacityIncrement;
}else{
newLength = (int)(elementData.length * 1.5);
}
elementData = new Object[newLength];
System.arraycopy(oldElemnts, 0, elementData, 0, size);
}
}
我们观察上述的pop方法,返回最后一个元素,然后size-1,咋一看没有问题,但是你返回了最后一个元素之后,最后一个元素还是占用内存的啊,
这就容易造成内存泄露,
推出去了就没有了,所以不能单单的返回,还要取消对象的引用
所以por方法应该如下:
Object ele = elemntData[--size];
//清除最后一个数组元素的引用,避免内存泄露
elementData[size] = null;
return ele;
大家以后写代码也要注意,
有时候还是有必要手动回收一下内存的。