日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

android内存不足,Android OutOfMemoryError:内存不足问题的排查与解决

發布時間:2025/4/16 Android 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 android内存不足,Android OutOfMemoryError:内存不足问题的排查与解决 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

程序出現了內存不足的問題。經過DDMS的監控,發現作為一個apk才十來M的程序,竟然把系統最多分配的128M內存占光光。經過一系列曲折的過程,基本查明了所有的問題所在。

內存泄露

為了便于理解,這里把一個對象里引用另一個對象的現象,稱為“持有”;把垃圾回收器及其動作,統稱為GC;如果A對象持有B對象,B對象又持有C對象,形成一個鏈條樣結構,稱為一個持有鏈。

GC的一個基本方法是“標記-清掃”,就是從堆棧和靜態存儲區出發,遍歷所有的對象和它們所持有的對象,形成一個樹形結構(稱為引用樹),對于被遍歷到的對象進行標記,最后釋放掉那些沒有被標記的對象。

堆棧和靜態存儲區里的對象,在這里通常被稱為GC Roots。根據這篇文章,靜態存儲區存保存的對象通常有以下幾類:

Class - 由系統類加載器(system class loader)加載的對象

Thread - 活著的線程

Stack Local - Java方法的local變量或參數

JNI Local - JNI方法的local變量或參數

JNI Global - 全局JNI引用

Monitor Used - 用于同步的監控對象

Held by JVM - 用于JVM特殊目的由GC保留的對象,但實際上這個與JVM的實現是有關的。

如果一個對象,直接或者間接地被上面這些GC Roots所持有的話,即使已經沒有用了,也不會被GC清理掉,內存泄漏就這樣產生了。

這種不合理的持有鏈通常有以下這些類型:

Android特有的隱式持有

與Java不同地,Android中會發生一些隱式的持有。比如,在一個Activity里,通過調用findById()、getDrawable()等函數的方式,獲取到一個畫面元素,那么這個元素就會隱式地持有當前的Activity作為mContext。一般情況下,這樣并沒有問題;但如果這個元素是作為靜態對象定義在Activity的類中,就不會被釋放,從而導致Activity也不能釋放。

Android內存泄漏排查工具:Leak Canary

這個工具引用到項目中后,在程序運行過程中,如果出現了內存泄露,就會自動提示在手機屏幕上;點擊通知區域中的相應條目,就可以看到泄露的Activity和相應的持有鏈,對于分析內存泄漏十分有效。

需要注意的是,因為需要以DebugCompile的方式編譯到程序中去,所以這個庫只有在Gradle構建的項目中才可以引用,基于Ant的項目就請先遷移到Gradle上去吧。

不合理的圖片-DPI對應

現在手機屏幕的效果越來越細膩,除了顏色越來越鮮艷之外,像素密度——DPI也越來越高(所謂的視網膜屏)。Android為了正確處理不同DPI下圖片顯示的效果,規定了程序的圖片按不同的DPI設計多套,分別分別存放在各自的目錄下的方法。在程序運行時,由系統挑選最合適的目錄進行顯示。

按DPI從小到大,這些目錄分別為: drawable-ldpi(低)→ drawable-mdpi(中)→ drawable-hdpi(高)→ drawable-xhdpi(超高)→ drawable-xxhdpi(超超高)→ ……

DPI并不等同于屏幕分辨率,也不等同于屏幕尺寸,它們之間的關系簡單來說就是: DPI×屏幕尺寸=分辨率。

但是由于這幾年的手機尺寸大部分都在5寸上下(需要兩只手抱著打電話的那種奇葩沒法說),所以剩下的兩個變量,DPI和分辨率之間是有一個粗略的對應關系的,如下表:

在設計圖片的時候,如果能按照上面這幾種尺寸分別設計好圖片,一般來說在分辨率上就不會有太大的偏差。

以上內容其實有點跑題了,那么圖片DPI和內存占用之間有什么關系呢?

非常有關系!經過dump heap,找到一些占用內存比較兇狠(5M起)的BitMap對象,對其中mData對象進行保存,并用 XXXXXXX打開(顯示出來),找到這張圖片后大吃一驚:一個10KB左右的圖片,在內存中竟然占到7MB!

上面這一系列操作的詳細方法點這里XXXXXXXXXX和這里XXXXXXXXX(待補充)。 順便吐槽下,IntelliJ比起Android Studio要先進好幾個版本,但是只要程序稍稍多占用點內存的時候,用IntelliJ dump heap完全不行,直接卡死,耽誤了好長時間,最后換了Android才完成。

言歸正傳,為什么一張圖片會占用這么大的內存空間?有些老舊的項目,最初不注意DPI的問題,甚至就直接把所有的圖片放在drawable下。這種情況下,其實是當作mdpi來處理的。但現在的手機屏幕,動輒都是xhdpi起,和mdpi之間相差兩三個檔次。

總結

以上是生活随笔為你收集整理的android内存不足,Android OutOfMemoryError:内存不足问题的排查与解决的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。