2017年9月11日 星期一

Activity context leak caused by getPackageManager

最近用 leakcanary 檢查有沒有 memory leak 的時候發現了 context leak,而 leak 的 memory 有 2MB 這麼多

context leak 是 android 最常發生的 memory leak 之一,吃掉的 memory 隨著你的 activity 大小而變,因為你的 activity context 無法釋放,隨著你的 activity 中持有的所有資源都會無法釋放

leakcanary 的強大功能就是會顯示出造成 memory leak 的來龍去脈,照著 leakcanary 的提示,是 UserManager 其中的一個 static variable reference 到我的 activity context,不過我沒有在 activity 中使用到 UserManager,怎麼會讓 context 被 UserManager 持有的

一番查證後,在我的 activity 中有去使用 PackageManager,而 PackageManager 內部使用到了 UserManager,而在 UserManager 第一次被使用到的時候會將自身存在一個 static variable 中,從而讓 context 被這個 static variable hold 住



android framework 用這樣的實作,難怪會有 memory leak,還讓你 leak 的不知不覺,只要用 activity context 呼叫 getPackageManager 就踩到坑裡

這個 memory leak 實際上是 android 5.0 的一個 bug,在 android 7.0 已經修正掉了,app 開發者要避開這個 memory leak 的話,需要用 application context 來呼叫 getPackageManage,而不是用 activity context

開發 android 時真的要小心,注意自己的 code 還不夠,還要注意不要掉到 android 挖好的洞裡

沒有留言:

張貼留言