前提
内存泄漏
当系统运行到某一时刻,某些占用着一定内存空间的操作或对象在之后都不会使用了,所以此时系统理应将这些内存空间给释放掉给接下来的系统运行使用,但是因为一些特殊的原因,从而导致这部分的内存空间一直无法释放,而这些无法释放的内存空间就会一直无法有效的被系统利用,俗称占着茅坑不拉屎,这一现象称之为内存泄漏。
危害
:一次内存泄漏并不会导致太大的问题,但如果不断累积多次内存泄漏,那么系统内存空间中的不可在被利用的内存将会越来越多,而可重复利用的内存越来越少,最终导致系统无法在从内存空间中申请内存运行程序,系统也就会报内存溢出(OOM)异常。
Java内部类和匿名内部类
在Java
语法中,如果在某个类中定义了非静态的内部类或者匿名内部类,那么这些非静态的内部类或者匿名内部类的实例对象必定会隐式的强引用
其外部类的实例对象。
例子:
public class Other {
}
public class Outer {
// 非静态的内部类
public class Inner {
public String publicString = "Inner.publicString";
}
public Inner getInner(){
// new Inner()创建的对象内部必定持有Outer类的一个实例对象
return new Inner();
}
// 非静态的匿名内部类的对象,其内部必定持有Outer类的一个实例对象
public Other other = new Other(){
public void fun(){
};
};
public Other getOther(){
return other;
}
public Other getOthers(){
// 非静态的匿名内部类的对象,其内部必定持有Outer类的一个实例对象
Other other = new Other(){
public void fun(){
};
};
return other;
}
}
Outer outer = new Outer();
// inner1对象内部必定隐式的持有outer对象
Outer.Inner inner1 = outer.new Inner();
// inner2对象内部必定隐式的持有outer对象
Outer.Inner inner2 = outer.getInner();
// other1对象内部必定隐式的持有outer对象
Other other1 = outer.getOther();
// other2对象内部必定隐式的持有outer对象
Other other2 = outer.getOthers();
要想消除非静态的内部类或者匿名内部类的实例对象隐式的强引用
其外部类的实例对象,只有将这些内部类或者匿名内部类声明为静态的内部类或者匿名内部类。
例子:
public class Other {
}
public class Outer {
// 静态的内部类
static public class Inner {
public String publicString = "Inner.publicString";
}
public Inner getInner(){
return new Inner()