一个生命周期长的对象引用了一个生命周期短的对象,导致短对象无法被回收
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
/**
* 这里需要一个回调对象,当前Activity实现了回调接口,并将当前Activity的引用传递给网络请求模块
* 当当前Activity被finish掉,但网络请求模块持有的Activity的引用还未释放(比如网络处理还未完成或者没有释放引用),
* 这时就会造成Activity无法被GC回收,造成内存泄漏
*/
netWorkManager.request(url,this);
/**
* 传递需要接口的对象就不会导致Activity泄漏了
*/
netWorkManager.request(url, new NewworkCallBack() {
@Override
public void onSuccess() {
}
@Override
public void onFail() {
}
});
}
@Override
public void onSuccess() {
}
@Override
public void onFail() {
}
}
与流有关的溢出,比如流没有被关闭
public class MemoryLeakDemo extends Activity{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
/**
* ref: http://stackoverflow.com/questions/9515465/strictmode-complains-about-inputstream-not-being-closed
*/
/**
* 看BufferedInputStream和FileInputStream的源码可知,它们的构造函数里会报异常,FileInputStream或BufferedInputStream对象会生成,
* 但 objectInputStream仍然为null,在finally代码块中就并不会close FileInputStream和BufferedInputStream对象
*/
ObjectInputStream objectInputStream;
File file;
try {
file = new File("demo/myfile");
objectInputStream = new ObjectInputStream(new BufferedInputStream(new FileInputStream(file)),STREAM_BUFFER_SIZE);
...
} catch (IOException e) {
e.printStackTrace();
}finally {
closeQuietly(objectInputStream);
}
/**
* 解决办法很简单
*/
FileInputStream fileInputStream;
BufferedInputStream bufferedInputStream;
ObjectInputStream objectInputStream;
File file;
try {
file = new File("demo/myfile");
fileInputStream = new FileInputStream(file);
bufferedInputStream = new BufferedInputStream(fileInputStream,STREAM_BUFFER_SIZE);
objectInputStream = new ObjectInputStream(bufferedInputStream);
...
} catch (IOException e) {
e.printStackTrace();
}finally {
closeQuietly(fileInputStream);
closeQuietly(bufferedInputStream);
closeQuietly(objectInputStream);
}
}
private void closeQuietly(InputStream is){
if(is != null){
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
与Context有关的溢出。
对于需要Context的长期存在的对象,要使用ApplicataionContext,而不要使用Activity的Context,否则会导致Activity无法被回收。
使用Activity的Context的对象的生命周期要和Activity一致。
不要在Activity内使用内部类,如果无法控制它的生命周期的话,使用静态内部类替代,并且用WeakReference引用外部的Activity。因为内部类会拿着外部类的引用,所以内部类有可能导致外部类无法被回收。
public class MemoryLeakDemo extends Activity{
private static Drawable sBackground;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
/**
* android应用中,对Context的不适当使用会造成Activity的无法被回收
* 比如此例中,large_bitmap是个大图片,这个Activity可能会启用多次,为了节省加载图片的时间,将其设成静态变量
* 这会提高速度,但会导致Activity无法被回收,因为View会作为Drawable的callback,Drawable拿着View的引用,
* View又拿着Activity的引用。
* 解决方法可以是,在Activity退出时将Drawable的callback置为null
*/
TextView label = new TextView(this);
label.setText("Leaks are bad");
if (sBackground == null) {
sBackground = getDrawable(R.drawable.large_bitmap);
}
label.setBackgroundDrawable(sBackground);
setContentView(label);
}
}