我当时正在玩一个空的示例项目,以使用RxJava订阅测试LeakCanary。为了创建内存泄漏,我创建了以下活动:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
Observable.interval(1, TimeUnit.SECONDS)
.subscribe {
Log.d("Interval", it.toString())
}
}
}
每次旋转设备时,都会创建活动的新实例,并且新的间隔开始打印计数。先前的计数器也继续打印到logcat。当我转储堆时,每次旋转屏幕时堆中都会有一个活动,这是我期望的,因为计数器仍在为每个活动运行,并且我没有处理订阅。
我不明白的是为什么LeakCanary未检测到内存泄漏?
如果我改为将活动创建为Java类而不为订阅者使用lambda,则每次旋转屏幕时都会检测到泄漏。实际上,检测到两个泄漏。第一个是ReportFragment
,它似乎是一个Android框架类,另一个是我的MainActivity
。
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Observable.interval(1, TimeUnit.SECONDS).subscribe(
new Consumer<Long>() {
@Override
public void accept(Long aLong) throws Exception {
Log.d("Interval", aLong.toString());
}
}
);
}
}
即使是陌生人,如果我将Java类转换为使用lambda,也将不再检测到泄漏!
LeakCanary版本1.6.1,Android编译/目标sdk28。