一、JVM中的垃圾回收机制虽然会回收不再使用的对象,但是回收机制是有前提的条件的,违背了前提条件则可能出现内存泄漏。而处于
内存泄漏的对象特点如下:
1、对象可达,即该对象还存在,还可以被访问
2、对象无用,该对象永远都不会再被使用。
二、过期引用
1、定义:永远都不会被解除的引用
2、特点:非常隐蔽,gc不会回收这种对象引用,而且也不会回收被该对象所引用的其他对象
3、坏处:内存泄漏
4、解决方法:一旦对象的引用过期,就立马进行清空操作,即引用置空。
5、场景:静态集合类的使用容易出现过期引用,因为静态变量的生命周期与应用程序的生命周期一致。
6、实例如下:
public class Stack {
Object[] mObjects;
private int mStackSize;
public Stack(int capacity) {
mObjects = new Object[capacity];
}
public void push(Object element) {
checkStackCapacity();
mObjects[mStackSize++] = element;
}
/*public Object pop() throws Exception {
if (0 == mStackSize)
throw new Exception();
return mObjects[--mStackSize];
}*/
public Object pop() throws Exception {
if (0 == mStackSize)
throw new Exception();
Object ret = mObjects[--mStackSize];
mObjects[mStackSize] = null;
return ret;
}
private void checkStackCapacity() {
if (mObjects.length == mStackSize) {
Object[] oldObjs = mObjects;
mObjects = new Object[2 * mObjects.length + 1];
System.arraycopy(oldObjs, 0, mObjects, 0, mStackSize);
}
}
public static void main(String[] args) {
Stack stack = new Stack(10);
for (int i = 0; i < 10; i++) {
stack.push("" + i);
System.out.println("push stack:" + stack.mObjects[i]);
}
try {
for (int i = 0; i < 10; i++) {
System.out.println("pop stack:" + stack.pop());
System.out.println("mObjects:" + stack.mObjects[i]);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
三、内存泄漏的三大来源
1、过期引用:一般出现在手动管理内存时
2、缓存:可使用弱引用来实现缓存
3、监听器或回调:一般需要遵循注册回调和反注册回调的操作即可避免内存泄漏