溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Android中內(nèi)存泄漏的注意點(diǎn)有哪些

發(fā)布時間:2021-10-13 15:26:39 來源:億速云 閱讀:107 作者:柒染 欄目:編程語言

Android中內(nèi)存泄漏的注意點(diǎn)有哪些,很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細(xì)講解,有這方面需求的人可以來學(xué)習(xí)下,希望你能有所收獲。

內(nèi)存泄漏對每一位 Android 開發(fā)一定是司空見慣,大家或多或少都肯定有些許接觸。大家都知道,每一個手機(jī)都有一定的承載上限,多處的內(nèi)存泄漏堆積一定會堆積如山,最終出現(xiàn)內(nèi)存爆炸 OOM。

而這,也是極有可能在 Android 面試中一道常見的開放題。

內(nèi)存泄漏的根本原因是一個長生命周期的對象持有了一個短生命周期的對象。如果你對垃圾回收機(jī)制有所了解,我想這個問題基本難不住你,因為知道了原理,自然不會去觸碰這些極易導(dǎo)致內(nèi)存泄漏的雷區(qū)。

該題重在積累,不需要死記硬背,自己多總結(jié)即可。

1. 長生命周期對象持有 Activity

這基本是最常見的內(nèi)存泄漏了,比如

內(nèi)部類形式使用 Handler 同時發(fā)送延時消息,或者在 Handler 里面執(zhí)行耗時任務(wù),在任務(wù)還沒完成的時候 Activity 需要銷毀。這時候由于 Handler 持有 Activity 的強(qiáng)引用導(dǎo)致 Activity 無法被回收。

同理內(nèi)部類形式的使用 AsyncTask 執(zhí)行耗時任務(wù)也會導(dǎo)致內(nèi)存泄漏的發(fā)生。

單例作為最長生命周期的對象,自然不應(yīng)該持有 Activity 從而導(dǎo)致內(nèi)存泄漏發(fā)生;

針對上面這種情況,基本不必多說了,不要使用內(nèi)部類或者匿名內(nèi)部類做這樣的處理就好了,實際上 IDE 也會彈出警告,我想大家應(yīng)該還是都知道采用靜態(tài)內(nèi)部類或者在銷毀頁面的時候使用相關(guān)方法移除處理的。

Activity 中匿名使用 Handler 實際上會導(dǎo)致 Handler 內(nèi)部類持有外部類的引用,而 SendMessage() 的時候 Message 會持有 Handler,enqueueMessage 機(jī)制又會導(dǎo)致 MeassageQueue 持有 Message。所以當(dāng)發(fā)送的是延遲消息那么 Message 并不會立即的遍歷出來處理而是阻塞到對應(yīng)的 Message 觸發(fā)時間以后再處理。那么阻塞的這段時間中頁面銷毀一定會造成內(nèi)存泄漏。

2. 各種注冊操作沒有對應(yīng)的反注冊

這一點(diǎn)基本不必多說,相信大家剛剛開始學(xué)習(xí)廣播和 Service 的時候一定對此有所接觸,然后就是比如我們常用的第三方框架 EventBus 也是一樣的。平時使用的時候注意在對應(yīng)的生命周期方法中進(jìn)行反注冊。

3. Bitmap 使用完沒有注意 recycle()

Bitmap 作為大對象,在使用完畢一定要注意調(diào)用 recycle() 進(jìn)行回收。TypedArray 、Cursor、各種流同理,一定要在最后調(diào)用自己的回收關(guān)閉方法處理。

4. WebView 使用不當(dāng)

WebView 是非常常用的控件,但稍有不注意也會導(dǎo)致內(nèi)存泄漏。內(nèi)存泄漏的場景: 很多人使用 Webview 都喜歡采用布局引用方式, 這其實也是作為內(nèi)存泄漏的一個隱患。當(dāng) Activity 被關(guān)閉時,Webview 不會被 GC 馬上回收,而是提交給事務(wù),進(jìn)行隊列處理,這樣就造成了內(nèi)存泄漏, 導(dǎo)致 Webview 無法及時回收。

目前所知的比較安全的方案是:

在布局中動態(tài)添加 WebView。

采用下面的方法。

override fun onDestroy() {  webView?.apply {    val parent = parent    if (parent is ViewGroup) {      parent.removeView(this)    }    stopLoading()    // 退出時調(diào)用此方法,移除綁定的服務(wù),否則某些特定系統(tǒng)會報錯    settings.javaScriptEnabled = false    clearHistory()    removeAllViews()    destroy()  }}

5. 循環(huán)引用

循環(huán)引用導(dǎo)致內(nèi)存泄漏比較少見,正常來講不會有人寫出 A 持有 B,B 持有 C,C 又持有A 這樣的代碼,不過總還是需要注意。

總的來說,內(nèi)存泄漏很常見,但檢測方式也很多。我們的 Android Studio 自帶的 Monitors 就可以幫我們找到大部分內(nèi)存問題,當(dāng)然我們也可以采用譬如 LeakCanary 這樣的庫去做檢測。

看完上述內(nèi)容是否對您有幫助呢?如果還想對相關(guān)知識有進(jìn)一步的了解或閱讀更多相關(guān)文章,請關(guān)注億速云行業(yè)資訊頻道,感謝您對億速云的支持。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI