你們有或常常碰到OOM的問題,對吧?不少這樣的問題只要一出現相信你們的想法跟個人同樣,就是本身的應用:優化、優化、再優化!並且若是出現相似於OOM這樣級別的問題,根本就很差處理,LogCat日誌中顯示的信息僅僅是OOM,並不會給你提示如何解決的方法或思路,由於引發OOM的緣由是你應用的問題,不是系統問題!應該想下,在優化以前找到須要優化的地方,再去作優化操做不是更直接嗎?相信大多數朋友應該常常聽過或使用Jnuit調試吧,好了,廢話很少說,今天就跟你們一塊兒來學習總結下OOM的調試方法,來找到須要優化的地方,要知道OOM也是能夠一步步調試的:javascript
if (cursor.moveToNext()) {
... ...
}
修正示例代碼:
Cursor cursor = null;
try {
cursor = getContentResolver().query(uri ...);
if (cursor != null && cursor.moveToNext()) {
... ...
}
} finally {
if (cursor != null) {
try {
cursor.close();
} catch (Exception e) {
//ignore this
}
}
}
複製代碼
同時,Android會爲每一個應用程序分配一個單獨的LINUX用戶。Android會盡可能保留一個正在運行進程,只在內存資源出現不足時,Android會嘗試中止一些進程從而釋放足夠的資源給其餘新的進程使用, 也能保證用戶正在訪問的當前進程有足夠的資源去及時地響應用戶的事件。Android會根據進程中運行的組件類別以及組件的狀態來判斷該進程的重要性,Android會首先中止那些不重要的進程。按照重要性從高到低一共有五個級別就是咱們常說的:前臺進程、可見進程、服務進程、後臺進程、空進程(此處概念略,你們本身查)
還有個小擴展:當一個程序第一次啓動時,Android會同時啓動一個對應的主線程(Main Thread),主線程主要負責處理與UI相關的事件,如用戶的按鍵事件,用戶接觸屏幕的事件以及屏幕繪圖事件,並把相關的事件分發到對應的組件進行處理。因此主線程一般又被叫作UI線程。在開發Android應用時必須遵照單線程模型的原則: Android UI操做並非線程安全的而且這些操做必須在UI線程中執行。Android的UI是單線程(Single-threaded)的。爲了不拖住GUI,一些較費時的對象應該交給獨立的線程去執行。若是幕後的線程來執行UI對象,Android就會發出錯誤訊息 CalledFromWrongThreadException。之後遇到這樣的異常拋出時就要知道怎麼回事咯!**php
** 好了,鋪墊知識就寫這麼多了,下面直接進入主題了:OOM調試**java
方式一:使用內存監測工具 DDMS –> Heap:(真機、模擬器都可使用)數據庫
** 1. 啓動eclipse後,切換到DDMS透視圖,並確認Devices視圖、Heap視圖都是打開的,沒打開的直接Window>ShowView>本身選;**
** 2. 將手機經過USB連接至電腦,連接時須要確認手機是處於「USB調試」模式**緩存
** 3. 連接成功後,在DDMS的Devices視圖中將會顯示手機設備的序列號,以及設備中正在運行的部分進程信息;**安全
** 4. 點擊選中想要監測的進程,若是在進程列表中未出現你的進程的話隨便選中一條讓Device一排的工具處於可用狀態,再點擊下Update Heap讓其自動找到咱們跑的應用的進程,好比臨時跑的兩個應用進程如圖eclipse
** 5. 點擊Heap視圖中的「Cause GC」按鈕;**工具
** 6.點擊Cause GC以後就能夠看到咱們應用的內存狀況以下圖:**學習
說明:
a) 點擊「Cause GC」按鈕至關於向虛擬機請求了一次gc操做;
b) 當內存使用信息第一次顯示之後,無須再不斷的點擊「Cause GC」,Heap視圖界面會定時刷新,在對應用的不斷的操做過程當中就能夠看到內存使用的變化;
c) 內存使用信息的各項參數根據名稱便可知道其意思,不知道具體意思的朋友自行用工具(有道、詞霸查去)測試
** 知道工具使用了,那麼如何才能知道咱們的程序是否有內存泄漏的可能性呢。這裏須要注意一個值:Heap視圖中部有一個Type叫作data object,即數據對象,也就是咱們的程序中大量存在的類類型的對象。在data object一行中有一列是「Total Size」,其值就是當前進程中全部Java數據對象的內存總量,若是你們想要看「Total Size」是分配的具體信息能夠點擊「data object這一行來查看詳細信息,以下圖」(你們看不清楚的點擊看大圖)**
通常狀況下,在data object行的「Total Size」這個值的大小決定了是否會有內存泄漏。能夠這樣判斷:
a) 不斷的操做當前應用,同時注意觀察data object的Total Size值;
b) 正常狀況下Total Size值都會穩定在一個有限的範圍內,也就是說因爲程序中的的代碼良好,沒有形成對象不被垃圾回收的狀況,因此說雖然咱們不斷的操做會不斷的生成不少對 象,而在虛擬機不斷的進行GC的過程當中,這些對象都被回收了,內存佔用量會會落到一個穩定的水平;
c) 反之若是代碼中存在沒有釋放對象引用的狀況,則data object的Total Size值在每次GC後不會有明顯的回落,隨着操做次數的增多Total Size的值會愈來愈大,
** 直到到達一個上限後致使進程被殺掉。**
** Android爲應用進程分配的內存上限以下所示:(下面這些是網上查到的,不懂下面的語法,但知道有限制這麼一回事就夠了,此處不研究下面的代碼)**
killed by the kernel. These are used in ActivityManagerService
setprop ro.FOREGROUND_APP_ADJ 0
setprop ro.VISIBLE_APP_ADJ 1
setprop ro.SECONDARY_SERVER_ADJ 2
setprop ro.BACKUP_APP_ADJ 2
setprop ro.HOME_APP_ADJ 4
setprop ro.HIDDEN_APP_MIN_ADJ 7
setprop ro.CONTENT_PROVIDER_ADJ 14
setprop ro.EMPTY_APP_ADJ 15
Define the memory thresholds at which the above process classes will
be killed. These numbers are in pages (4k)
setprop ro.FOREGROUND_APP_MEM 1536
setprop ro.VISIBLE_APP_MEM 2048
setprop ro.SECONDARY_SERVER_MEM 4096
setprop ro.BACKUP_APP_MEM 4096
setprop ro.HOME_APP_MEM 4096
setprop ro.HIDDEN_APP_MEM 5120
setprop ro.CONTENT_PROVIDER_MEM 5632
setprop ro.EMPTY_APP_MEM 6144
Write value must be consistent with the above properties.
Note that the driver only supports 6 slots, so we have HOME_APP at the
same memory level as services.
write /sys/module/lowmemorykiller/parameters/adj 0,1,2,7,14,15
write /proc/sys/vm/overcommit_memory 1
write /proc/sys/vm/min_free_order_shift 4
write /sys/module/lowmemorykiller/parameters/minfree 1536,2048,4096,5120,5632,6144
Set init its forked children’s oom_adj
write /proc/1/oom_adj -16
複製代碼
方式二:
**內存監測工具 DDMS –> Heap **
**使用內存分析工具 MAT(Memory Analyzer Tool) **
(一) 生成.hprof文件 (生成很簡單,直接點擊Device 工具欄中的 Dump HPROF file便可生成)
**(二) 使用MAT導入.hprof文件 **
(三) 使用MAT的視圖工具分析內存
** 總之,使用DDMS的Heap視圖工具能夠很方便的確認咱們的程序是否存在內存泄漏的可能性。這個地方順帶着也簡單的說一下,若是你們想要跟蹤更詳細的內存是怎樣分配的話,能夠學着使用下Windows>ShowView>Allocation Tracker工具來定位你的內存何時被什麼東西佔用了,是bundlea或HashMap或ArrayList焦點或是其它的什麼佔用了這些均可以在這個插件中查看到的,簡單的使用方法就是:選中Device進程列表中的某一個進程,讓Allocation Tracker裏面的跟蹤工具處於可用狀態,點擊Stop Tracking來跟蹤程序,過必定時間後,點擊Get Allocations來獲取內存分配的消息就能夠查看更爲詳細的內存分配狀況了,以下圖:**
** Allocation Tracker這個小工具比較簡單, 在這個地方不一一說明了,想學的朋友們本身點擊看看就會知道里面的參數是什麼意思了….._……..****最後,仍是同樣,在內存管理方面還要學的東西不少,若是文章中有講的不清楚或不足之處,你們留言批評並提出更好的建議,必定及時改進,在此先謝謝你們啦,吼吼學習學習!你們加油,一塊兒進步!!!