Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Android内存泄漏GC Root分析总结 #107

Open
zgq105 opened this issue Dec 18, 2023 · 0 comments
Open

Android内存泄漏GC Root分析总结 #107

zgq105 opened this issue Dec 18, 2023 · 0 comments

Comments

@zgq105
Copy link
Owner

zgq105 commented Dec 18, 2023

1. 内存泄漏的原因?

内存泄漏的本质是长生命周期的对象持有短生命周期对象的引用,导致本应该被回收的短生命周期对象不能被GC回收导致内存泄漏。

2. Hander内存泄漏分析?

class BActivity : AppCompatActivity() {
    
    inner class MyHandler : Handler(Looper.getMainLooper()) {
        override fun handleMessage(msg: Message) {
            super.handleMessage(msg)
            Log.d("zgq", "handleMessage:${msg.what}")
        }
    }

   private val myHandler = MyHandler()
   override fun onResume() {
        super.onResume()
        //模拟handler内存泄漏,启动页面然后马上关闭页面
        myHandler.sendEmptyMessageDelayed(1103, 20 * 1000)
   }

}

从上面这里实例代码我们知道可以通过Profiler或者leakcanary都会发现内存泄漏了,通过阅读源码可以知道以下的引用链:

ActivityThread中主线程 -> ThreadLocalMap -> ThreadLocal -> Looper -> MessageQueue -> Message -> Handler -> Activity

因为主线程是一直存在的,导致引用链不能被回收,进而导致Activity 实例发生内存泄漏的根本原因。GC Root引用链已经列出来了,重点查看以上相关的源码还是很好理解的。所以这里的GC Root主线程对象。

3.线程内存泄漏分析?

class BActivity : AppCompatActivity() {
    
    inner class MyHandler : Handler(Looper.getMainLooper()) {
        override fun handleMessage(msg: Message) {
            super.handleMessage(msg)
            Log.d("zgq", "handleMessage:${msg.what}")
        }
    }

   private val myHandler = MyHandler()
   override fun onResume() {
        super.onResume()
       //模拟子线程内存泄漏,启动页面然后马上关闭页面
        Thread {
            Thread.sleep(20 * 1000)
            myHandler.sendEmptyMessage(11)
            Log.d("zgq", "thread:end")
        }.start()
   }

}

按相同的方式分析以上代码的引用链是:子线程 -> Handler -> Activity ,因为这里是子线程对象引用了Handler对象 ,而Handler 对象又引用了Activity对象,导致内存泄漏;这里的GC Root就是子线程的实例对象。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant