android crash治理:
我的crash治理:
- 代碼邏輯上的錯誤引發(fā)的crash-----修復并總結
- 兼容性問題導致的crash
- 內存導致的crash---內存問題可能引發(fā)卡頓碰凶、cpu增長砾省、oom
遇到一些和系統(tǒng)相關的問題,要去查看對應版本的源碼田轧,從源碼中查看可能出現(xiàn)問題的原因。
美團外賣總結
常規(guī)crash
NullPointerException 為初始化覆旱,或者在使用過程中未判空痘番,多線程變量可見性受到影響。
IndexOutOfBoundsException等
系統(tǒng)crash
一些廠商經過系統(tǒng)定制導致的問題蝙茶,通過java hook 和native hook 的方式進行解決艺骂。
下面是常見的解決思路:
嘗試找到造成Crash的可疑代碼,看是否有特異的API或者調用方式不當導致的隆夯,嘗試修改代碼邏輯來進行規(guī)避钳恕。
通過Hook來解決,Hook分為Java Hook和Native Hook蹄衷。Java Hook主要靠反射或者動態(tài)代理來更改相應API的行為忧额,需要嘗試找到可以Hook的點,一般Hook的點多為靜態(tài)變量愧口,同時需要注意Android不同版本的API睦番,類名、方法名和成員變量名都可能不一樣耍属,所以要做好兼容工作托嚣;Native Hook原理上是用更改后方法把舊方法在內存地址上進行替換,需要考慮到Dalvik和ART的差異厚骗;相對來說Native Hook的兼容性更差一點示启,所以用Native Hook的時候需要配合降級策略。
如果通過前兩種方式都無法解決的話领舰,我們只能嘗試反編譯ROM夫嗓,尋找解決的辦法。
OOM
常見內存問題引發(fā)的oom
常見的 oom 問題一般分為
java 內存溢出
無連續(xù)可用空間
java.lang.OutOfMemoryError: Failed to allocate a 9224 byte allocation with 8384232 free bytes and 15MB until OOM; failed due to fragmentation (required continguous free 12288 bytes where largest contiguous free 8192 bytes)
FD 數量超出限制
線程數量超出限制
虛擬內存不足
進程間內存分配
cpu和gpu使用同一個RAM
RAM 分為多個“頁面”提揍。通常啤月,每個頁面為 4KB 的內存。
系統(tǒng)會將頁面視為“可用”或“已使用”劳跃』阎伲可用頁面是未使用的 RAM。已使用的頁面是系統(tǒng)當前正在使用的 RAM刨仑,并分為以下類別:
- 緩存頁:有存儲器中的文件(例如代碼或內存映射文件)支持的內存郑诺。緩存內存有兩種類型:
- 匿名頁:沒有存儲器中的文件支持的內存(例如飞涂,由設置了
MAP_ANONYMOUS
標記的mmap()
進行分配)- 臟頁:可由
kswapd
移動到 zRAM/在 zRAM 中進行壓縮以增加可用內存
- 臟頁:可由
注意:干凈頁包含存在于存儲器中的文件(或文件一部分)的精確副本旦部。如果干凈頁不再包含文件的精確副本(例如,因應用操作所致)较店,則會變成臟頁士八。干凈頁可以刪除,因為始終可以使用存儲器中的數據重新生成它們梁呈;臟頁則不能刪除婚度,否則數據將會丟失。
https://developer.android.google.cn/topic/performance/memory-management
內存管理方案·
系統(tǒng)層面
- kswapd機制 共享頁官卡,匿名頁(臟頁蝗茁,干凈頁)
- LMK機制
- 配合框架自身的生命周期管理機制。
內存回調:
onTrimMemory寻咒,可以在 Application哮翘,Activiy,Service 和 ContentProvider 中重寫接口方法來實現(xiàn)內存變化的監(jiān)聽ComponentCallbacks2
public interface ComponentCallbacks2 extends ComponentCallbacks {
/** @hide */
@IntDef(prefix = { "TRIM_MEMORY_" }, value = {
TRIM_MEMORY_COMPLETE,
TRIM_MEMORY_MODERATE,
TRIM_MEMORY_BACKGROUND,
TRIM_MEMORY_UI_HIDDEN,
TRIM_MEMORY_RUNNING_CRITICAL,
TRIM_MEMORY_RUNNING_LOW,
TRIM_MEMORY_RUNNING_MODERATE,
})
@Retention(RetentionPolicy.SOURCE)
public @interface TrimMemoryLevel {}
..........
void onTrimMemory(@TrimMemoryLevel int level);