Я играл с пустым примером проекта, чтобы протестировать LeakCanary с подписками RxJava.Чтобы создать утечку памяти, я создал следующее действие:
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 без использования лямбды для подписчика, утечка обнаруженакаждый раз, когда я поворачиваю экран.На самом деле обнаружены две утечки.Первый для 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 в лямбду, утечкабольше не обнаружен!
LeakCanary версия 1.6.1, Android compile / target sdk 28.