内存泄漏详细解析 - 1835434698/1835434698.github.io GitHub Wiki
内存泄漏(Memory Leak)是指程序中已动态分配的堆内存由于某种原因程序未释放或无法释放,造成系统内存的浪费,导致程序运行速度减慢甚至系统崩溃等严重后果。
Android中内存泄漏大部分情况是因为内部类导致的,内部类会持有外部类的引用,但是外部类销毁回收的时候内部类还在执行,导致外部类不能被回收。
private static final String TAG = "ThreadMainActivity";
private int i = 0;
private int j = 0;
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d(TAG, "onCreate");
runTask();
}
private void runTask() {
Observable.create(new ObservableOnSubscribe<Object>() {
@Override
public void subscribe(ObservableEmitter<Object> emitter){
try {
Log.d(TAG, "work run name : "+Thread.currentThread().getName());
workTask();
emitter.onNext("");
}catch (Exception e){
Log.d("ThreadMainActivity", "e12 = "+e.getMessage());
}
}
}).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
.as(AutoDispose.autoDisposable(AndroidLifecycleScopeProvider.from(this)))
.subscribe(new Consumer<Object>() {
@Override
public void accept(Object integer) throws Exception {
Log.d(TAG, "UI run i = " + i + " j = " + j + " name : " + Thread.currentThread().getName());
uiTask();
}
});
}
private void uiTask() {
j++;
runTask();
}
private void workTask() throws InterruptedException {
i = 0;
Log.d(TAG, "work run i = "+i+" j = "+j);
if (j >= 10){
throw new InterruptedException();
}
while (i< 10){
Log.d(TAG, "i++");
i++;
Thread.sleep(100);
}
}
此种写法有两个匿名内部类分别是ObservableOnSubscribe与Consumer,但是触发GC的时候会先把匿名内部类回收掉。
private static final String TAG = "ThreadMainActivity";
private int i = 0;
private int j = 0;
private ObservableOnSubscribe<Object> objectObservableOnSubscribe;
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d(TAG, "onCreate");
runTask();
}
private void runTask() {
objectObservableOnSubscribe = new ObservableOnSubscribe<Object>() {
@Override
public void subscribe(ObservableEmitter<Object> emitter){
try {
Log.d(TAG, "work run name : "+Thread.currentThread().getName());
workTask();
emitter.onNext("");
}catch (Exception e){
Log.d("ThreadMainActivity", "e12 = "+e.getMessage());
}
}
};
Consumer<Object> consumer = new Consumer<Object>() {
@Override
public void accept(Object integer) throws Exception {
Log.d(TAG, "UI run i = " + i + " j = " + j + " name : " + Thread.currentThread().getName());
uiTask();
}
};
Observable.create(objectObservableOnSubscribe).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
.as(AutoDispose.autoDisposable(AndroidLifecycleScopeProvider.from(this)))
.subscribe(consumer);
}
private void uiTask() {
j++;
runTask();
}
private void workTask() throws InterruptedException {
i = 0;
Log.d(TAG, "work run i = "+i+" j = "+j);
if (j >= 10){
throw new InterruptedException();
}
while (i< 10){
Log.d(TAG, "i++");
i++;
Thread.sleep(100);
}
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.d(TAG, "onDestroy");
objectObservableOnSubscribe = null;
}
此种写法Consumer容易被回收,ObservableOnSubscribe的大部分会被回收,但是最好一个new的不容易被回收,但是可以在onDestroy使objectObservableOnSubscribe = null;几可以使其被回收。