如何发现内存泄露问题?
通过andriod studio提供的工具,分析Memory,获取一段内存情况之前,记得多点两下强制GC,以便分析的准确些。
分析结果如下图所示:
分析代码,查看内存泄露的根本原因
SubmitDialogFragment类写了如下代码
companion object {
var submitDialogFragment: SubmitDialogFragment? = null
@JvmStatic
fun newInstance(): SubmitDialogFragment {
val args = Bundle()
submitDialogFragment = SubmitDialogFragment()
submitDialogFragment!!.arguments = args
return submitDialogFragment!!
}
fun show(
fragmentManager: FragmentManager,
confirmListener: ConfirmListener,
content: String? = null
):SubmitDialogFragment {
submitDialogFragment = newInstance()
submitDialogFragment?.setContent(content)
submitDialogFragment!!.mConfirmListener = confirmListener
//设置普通样式,全屏风格
submitDialogFragment!!.setStyle(STYLE_NORMAL, R.style.Dialog_FullScreen)
submitDialogFragment!!.show(fragmentManager, "")
return submitDialogFragment!!
}
fun dismissDialog() {
submitDialogFragment?.dismiss()
}
fun dialogIsVisible(): Boolean {
return submitDialogFragment != null && submitDialogFragment!!.isVisible
}
}
查看build目录下生成的java字节码
public final class SubmitDialogFragment extends DialogFragment implements OnKeyListener, OnCancelListener {
private View rootView;
private String content;
private SubmitDialogFragment.ConfirmListener mConfirmListener;
@Nullable
private static SubmitDialogFragment submitDialogFragment;
public static final SubmitDialogFragment.Companion Companion = new SubmitDialogFragment.Companion((DefaultConstructorMarker)null);
private HashMap _$_findViewCache;
发现泄漏的根本原因
private static SubmitDialogFragment submitDialogFragment;
回忆一下背过的理论知识,可以作为GCRoot根其中之一就是类的静态成员变量引用的对象。
其余三个是虚拟机栈中引用的对象,本地方法栈引用的对象,常量(final)引用的对象
解决方案
把引用置为null,submitDialogFragment的实例就会被回收了
fun dismissDialog() {
submitDialogFragment?.dismiss()
//解决方案
submitDialogFragment = null
}
总结
- kotlin的companion object内部var声明的变量会被java转化为static。
- 尽量不要用静态变量的引用带有生命周期的对象。