内存优化:内存泄露案例一"/>
Android内存优化:内存泄露案例一
单例引起的内存泄露
单例在使用的时候,处理不当很容易造成内存泄露,下面是一个使用中造成内存泄露的案例。
城市选择器从本地加载数据,为了不每次打开都加载一次,这边使用了单例来管理,只加载一次,
fun showCitySelector(activity: Activity,onCitySelectorShowListener: OnCitySelectorShowListener,onCitySelectedListener: OnCitySelectedListener){this.onCitySelectorShowListener = onCitySelectorShowListenerthis.onCitySelectedListener = onCitySelectedListener//弱应用防止内存泄露this.activity = WeakReference(activity)if(options1Items.size <= 0)getCityData()else {showCitySelectorInternal()}}
在fragmentA中调用:
CitySelector.instance.showCitySelector(activity,object : CitySelector.OnCitySelectorShowListener{override fun onCitySelectorShow() {}}, object : CitySelector.OnCitySelectedListener{override fun onCitySelected(provinceId: String?,cityId: String?,districtId: String?,address: String?) {region_selector.setValue(address)mProvinceId = provinceIdmCityId = cityIdmDistrictId = districtId}})
activity使用虚引用,但是onCitySelectorShowListener 和onCitySelectedListener 使用的是强应用,onCitySelectorShowListener 和onCitySelectedListener 是在fragmentA定义的匿名内部类,持有了fragmentA的引用,这样就相当于CitySelector单例中持有了fragmenA的引用,导致fragmentA无法回收,继而activity无法回收,造成内存泄露。
使用Profiler查看到的情况,有5个内存泄露点
MyApartmentListFragment是上面的fragmentA,打开了城市选择器。
观察它的被引用情况(勾选Show nearest GC root only):
发现ApartmentInfoEditDialog中的this$0(即匿名内部类)被CitySelector中的onCitySelectedListener对象持有了,无法回收
更多推荐
Android内存优化:内存泄露案例一
发布评论