當前位置:首頁 » 安卓系統 » memoryandroid

memoryandroid

發布時間: 2022-11-26 12:33:55

『壹』 為什麼android虛擬機內存顯示還有13%就報out of memory

如果你是看操作系統的 內存還剩 13%,但是虛擬機的內存可能已經用完了。虛擬機啟動的時候,會預先分配內存。如果是普通java程序 JVM啟動的時候也是預先確定最大內存。而android虛擬機 AVD,在創建機型的時候,也是有設置虛擬機的地方。


『貳』 如何檢查 Android 應用的內存使用情況

解析日誌信息
最簡單的調查應用內存使用情況的地方就是Dalvik日誌信息。可以在logcat(輸出信息可以在Device Monitor或者IDE中查看到,例如Eclipse和Android Studio)中找到這些日誌信息。每次有垃圾回收發生,logcat會列印出帶有下面信息的日誌消息:

Java

1

D/dalvikvm: <GC_Reason> <Amount_freed>, <Heap_stats>, <External_memory_stats>, <Pause_time>

GC原因
觸發垃圾回收執行的原因和垃圾回收的類型。原因主要包括:
GC_CONCURRENT
並發垃圾回收,當堆開始填滿時觸發來釋放內存。
GC_FOR_MALLOC
堆已經滿了時應用再去嘗試分配內存觸發的垃圾回收,這時系統必須暫停應用運行來回收內存。
GC_HPROF_DUMP_HEAP
創建HPROF文件來分析應用時觸發的垃圾回收。
GC_EXPLICIT
顯式垃圾回收,例如當調用 gc()(應該避免手動調用而是要讓垃圾回收器在需要時主動調用)時會觸發。
GC_EXTERNAL_ALLOC
這種只會在API 10和更低的版本(新版本內存都只在Dalvik堆中分配)中會有。回收外部分配的內存(例如存儲在本地內存或NIO位元組緩沖區的像素數據)。
釋放數量
執行垃圾回收後內存釋放的數量。
堆狀態
空閑的百分比和(活動對象的數量)/(總的堆大小)。
外部內存狀態
API 10和更低版本中的外部分配的內存(分配的內存大小)/(回收發生時的限制值)。
暫停時間
越大的堆的暫停時間就越長。並發回收暫停時間分為兩部分:一部分在回收開始時,另一部分在回收將近結束時。
例如:

Java

1

D/dalvikvm( 9050): GC_CONCURRENT freed 2049K, 65% free 3571K/9991K, external 4703K/K, paused 2ms+2ms

隨著這些日誌消息的增多,注意堆狀態(上面例子中的3571K/9991K)的變化。如果值一直增大並且不會減小下來,那麼就可能有內存泄露了。
查看堆的更新
為了得到應用內存的使用類型和時間,可以在Device Monitor中實時查看應用堆的更新:
1.打開Device Monitor。
從<sdk>/tools/路徑下載入monitor工具。
2.在Debug Monitor窗口,從左邊的進程列表中選擇要查看的應用進程。
3.點擊進程列表上面的Update Heap。
4.在右側面板中選擇Heap標簽頁。

Heap視圖顯示了堆內存使用的基本狀況,每次垃圾回收後會更新。要看更新後的狀態,點擊Gause GC按鈕。

圖1.Device Monitor工具顯示[1] Update Heap和 [2] Cause GC按鈕。右邊的Heap標簽頁顯示堆的情況。
跟蹤內存分配
當要減少內存問題時,應該使用Allocation Tracker來更好的了解內存消耗大戶在哪分配。Allocation Tracker不僅在查看內存的具體使用上很有用,也可以分析應用中的關鍵代碼路徑,例如滑動。
例如,在應用中滑動列表時跟蹤內存分配,可以看到內存分配的動作,包括在哪些線程上分配和哪裡進行的分配。這對優化代碼路徑來減輕工作量和改善UI流暢性都極其有用。
使用Allocation Tracker:
1.打開Device Monitor 。
從<sdk>/tools/路徑下載入monitor工具。
2.在DDMS窗口,從左側面板選擇應用進程。
3.在右側面板中選擇Allocation Tracker標簽頁。
4.點擊Start Tracking。
5.執行應用到需要分析的代碼路徑處。
6.點擊Get Allocations來更新分配列表。
列表顯示了所有的當前分配和512大小限制的環形緩沖區的情況。點擊行可以查看分配的堆棧跟蹤信息。堆棧不只顯示了分配的對象類型,還顯示了屬於哪個線程哪個類哪個文件和哪一行。

圖2. Device Monitor工具顯示了在Allocation Tracker中當前應用的內存分配和堆棧跟蹤的情況。
注意:總會有一些分配是來自與 DdmVmInternal 和 allocation tracker本身。
盡管移除掉所有嚴重影響性能的代碼是不必要的(也是不可能的),但是allocation tracker還是可以幫助定位代碼中的嚴重問題。例如,應用可能在每個draw操作上創建新的Paint對象。把對象改成全局變數就是一個很簡單的改善性能的修改。
查看總體內存分配
為了進一步的分析,查看應用內存中不同內存類型的分配情況,可以使用下面的 adb 命令:

Java

1

adb shell mpsys meminfo <package_name>

應用當前的內存分配輸出列表,單位是千位元組。
當查看這些信息時,應當熟悉下面的分配類型:
私有(Clean and Dirty) 內存
進程獨占的內存。也就是應用進程銷毀時系統可以直接回收的內存容量。通常來說,「private dirty」內存是其最重要的部分,因為只被自己的進程使用。它只在內存中存儲,因此不能做分頁存儲到外存(Android不支持swap)。所有分配的Dalvik堆和本地堆都是「private dirty」內存;Dalvik堆和本地堆中和Zygote進程共享的部分是共享dirty內存。
實際使用內存 (PSS)
這是另一種應用內存使用的計算方式,把跨進程的共享頁也計算在內。任何獨占的內存頁直接計算它的PSS值,而和其它進程共享的頁則按照共享的比例計算PSS值。例如,在兩個進程間共享的頁,計算進每個進程PPS的值是它的一半大小。
PSS計算方式的一個好處是:把所有進程的PSS值加起來就可以確定所有進程總共佔用的內存。這意味著用PSS來計算進程的實際內存使用、進程間對比內存使用和總共剩餘內存大小是很好的方式。
例如,下面是平板設備中Gmail進程的輸出信息。它顯示了很多信息,但是具體要講解的是下面列出的一些關鍵信息。
注意:實際看到的信息可能和這里的稍有不同,輸出的詳細信息可能會根據平台版本的不同而不同。

Java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

** MEMINFO in pid 9953 [com.google.android.gm] **
Pss Pss Shared Private Shared Private Heap Heap Heap
Total Clean Dirty Dirty Clean Clean Size Alloc Free
------ ------ ------ ------ ------ ------ ------ ------ ------
Native Heap 0 0 0 0 0 0 7800 7637(6) 126
Dalvik Heap 5110(3) 0 4136 4988(3) 0 0 9168 8958(6) 210
Dalvik Other 2850 0 2684 2772 0 0
Stack 36 0 8 36 0 0
Cursor 136 0 0 136 0 0
Ashmem 12 0 28 0 0 0
Other dev 380 0 24 376 0 4
.so mmap 5443(5) 1996 2584 2664(5) 5788 1996(5)
.apk mmap 235 32 0 0 1252 32
.ttf mmap 36 12 0 0 88 12
.dex mmap 3019(5) 2148 0 0 8936 2148(5)
Other mmap 107 0 8 8 324 68
Unknown 6994(4) 0 252 6992(4) 0 0
TOTAL 24358(1) 4188 9724 17972(2)16388 4260(2)16968 16595 336

Objects
Views: 426 ViewRootImpl: 3(8)
AppContexts: 6(7) Activities: 2(7)
Assets: 2 AssetManagers: 2
Local Binders: 64 Proxy Binders: 34
Death Recipients: 0
OpenSSL Sockets: 1

SQL
MEMORY_USED: 1739
PAGECACHE_OVERFLOW: 1164 MALLOC_SIZE: 62

通常來說,只需關心Pss Total列和Private Dirty列就可以了。在一些情況下,Private Clean列和Heap Alloc列也會提供很有用的信息。下面是一些應該查看的內存分配類型(行中列出的類型):
Dalvik Heap
應用中Dalvik分配使用的內存。Pss Total包含所有的Zygote分配(如上面PSS定義所描述的,共享跨進程的加權)。Private Dirty是應用堆獨占的內存大小,包含了獨自分配的部分和應用進程從Zygote復制分裂時被修改的Zygote分配的內存頁。
注意:新平台版本有Dalvik Other這一項。Dalvik Heap中的Pss Total和Private Dirty不包括Dalvik的開銷,例如即時編譯(JIT)和垃圾回收(GC),然而老版本都包含在Dalvik的開銷裡面。
Heap Alloc是應用中Dalvik堆和本地堆已經分配使用的大小。它的值比Pss Total和Private Dirty大,因為進程是從Zygote中復制分裂出來的,包含了進程共享的分配部分。
.so mmap和.dex mmap
mmap映射的.so(本地) 和.dex(Dalvik)代碼使用的內存。Pss Total 包含了跨應用共享的平台代碼;Private Clean是應用獨享的代碼。通常來說,實際映射的內存大小要大一點——這里顯示的內存大小是執行了當前操作後應用使用的內存大小。然而,.so mmap 的private dirty比較大,這是由於在載入到最終地址時已經為本地代碼分配好了內存空間。
Unknown
無法歸類到其它項的內存頁。目前,這主要包含大部分的本地分配,就是那些在工具收集數據時由於地址空間布局隨機化(Address Space Layout Randomization ,ASLR)不能被計算在內的部分。和Dalvik堆一樣, Unknown中的Pss Total把和Zygote共享的部分計算在內,Unknown中的Private Dirty只計算應用獨自使用的內存。
TOTAL
進程總使用的實際使用內存(PSS),是上面所有PSS項的總和。它表明了進程總的內存使用量,可以直接用來和其它進程或總的可以內存進行比較。
Private Dirty和Private Clean是進程獨自佔用的總內存,不會和其它進程共享。當進程銷毀時,它們(特別是Private Dirty)佔用的內存會重新釋放回系統。Dirty內存是已經被修改的內存頁,因此必須常駐內存(因為沒有swap);Clean內存是已經映射持久文件使用的內存頁(例如正在被執行的代碼),因此一段時間不使用的話就可以置換出去。
ViewRootImpl
進程中活動的根視圖的數量。每個根視圖與一個窗口關聯,因此可以幫助確定涉及對話框和窗口的內存泄露。
AppContexts和Activities
當前駐留在進程中的Context和Activity對象的數量。可以很快的確認常見的由於靜態引用而不能被垃圾回收的泄露的 Activity對象。這些對象通常有很多其它相關聯的分配,因此這是追查大的內存泄露的很好辦法。
注意:View 和 Drawable 對象也持有所在Activity的引用,因此,持有View 或 Drawable 對象也可能會導致應用Activity泄露。
獲取堆轉儲
堆轉儲是應用堆中所有對象的快照,以二進制文件HPROF的形式存儲。應用堆轉儲提供了應用堆的整體狀態,因此在查看堆更新的同時,可以跟蹤可能已經確認的問題。
檢索堆轉儲:
1.打開Device Monitor。
從<sdk>/tools/路徑下載入monitor工具。
2.在DDMS窗口,從左側面板選擇應用進程。
3.點擊Dump HPROF file,顯示見圖3。
4.在彈出的窗口中,命名HPROF文件,選擇存放位置,然後點擊Save。

圖3.Device Monitor工具顯示了[1] Dump HPROF file按鈕。
如果需要能更精確定位問題的堆轉儲,可以在應用代碼中調用mpHprofData()來生成堆轉儲。
堆轉儲的格式基本相同,但與Java HPROF文件不完全相同。Android堆轉儲的主要不同是由於很多的內存分配是在Zygote進程中。但是由於Zygote的內存分配是所有應用進程共享的,這些對分析應用堆沒什麼關系。
為了分析堆轉儲,你需要像jhat或Eclipse內存分析工具(MAT)一樣的標准工具。當然,第一步需要做的是把HPROF文件從Android的文件格式轉換成J2SE HRPOF的文件格式。可以使用<sdk>/platform-tools/路徑下的hprof-conv工具來轉換。hprof-conv的使用很簡單,只要帶上兩個參數就可以:原始的HPROF文件和轉換後的HPROF文件的存放位置。例如:

Java

1

hprof-conv heap-original.hprof heap-converted.hprof

注意:如果使用的是集成在Eclipse中的DDMS,那麼就不需要再執行HPROF轉換操作——默認已經轉換過了。
現在就可以在MAT中載入轉換過的HPROF文件了,或者是在可以解析J2SE HPROF格式的其它堆分析工具中載入。
分析應用堆時,應該查找由下導致的內存泄露:
對Activity、Context、View、Drawable的長期引用,以及其它可能持有Activity或Context容器引用的對象
非靜態內部類(例如持有Activity實例的Runnable)
不必要的長期持有對象的緩存
使用Eclipse內存分析工具
Eclipse內存分析工具(MAT)是一個可以分析堆轉儲的工具。它是一個功能相當強大的工具,功能遠遠超過這篇文檔的介紹,這里只是一些入門的介紹。

在MAT中打開類型轉換過的HPROF文件,在總覽界面會看到一張餅狀圖,它展示了佔用堆的最大對象。在圖表下面是幾個功能的鏈接:
Histogram view顯示所有類的列表和每個類有多少實例。
正常來說類的實例的數量應該是確定的,可以用這個視圖找到額外的類的實例。例如,一個常見的源碼泄露就是Activity類有額外的實例,而正確的是在同一時間應該只有一個實例。要找到特定類的實例,在列表頂部的<Regex>域中輸入類名查找。
當一個類有太多的實例時,右擊選擇List objects>with incoming references。在顯示的列表中,通過右擊選擇Path To GC Roots> exclude weak references來確定保留的實例。
Dominator tree是按照保留堆大小來顯示的對象列表。
應該注意的是那些保留的部分堆大小粗略等於通過GC logs、heap updates或allocation tracker觀察到的泄露大小的對象。
當看到可疑項時,右擊選擇Path To GC Roots>exclude weak references。打開新的標簽頁,標簽頁中列出了可疑泄露的對象的引用。
注意:在靠近餅狀圖中大塊堆的頂部,大部分應用會顯示Resources的實例,但這通常只是因為在應用使用了很多res/路徑下的資源。

圖4.MAT顯示了Histogram view和搜索」MainActivity」的結果。
想要獲得更多關於MAT的信息,請觀看2011年Google I/O大會的演講–《Android 應用內存管理》(Memory management for Android apps),在大約21:10 的時候有關於MAT的實戰演講。也可以參考文檔《Eclipse 內存分析文檔》(Eclipse Memory Analyzer documentation)。
對比堆轉儲
為了查看內存分配的變化,比較不同時間點應用的堆狀態是很有用的方法。對比兩個堆轉儲可以使用MAT:
1.按照上面描述得到兩個HPROF文件,具體查看獲取堆轉儲章節。
2.在MAT中打開第一個HPROF文件(File>Open Heap Dump)。
3.在Navigation History視圖(如果不可見,選擇Window>Navigation History),右擊Histogram,選擇Add to Comp are Basket。
4.打開第二個HRPOF文件,重復步驟2和3。
5.切換到Compare Basket視圖,點擊Compare the Results(在視圖右上角的紅色「!」圖標)。
觸發內存泄露
使用上述描述工具的同時,還應該對應用代碼做壓力測試來嘗試復現內存泄露。一個檢查應用潛在內存泄露的方法,就是在檢查堆之前先運行一會。泄露會慢慢達到分配堆的大小的上限值。當然,泄露越小,就要運行應用越長的時間來復現。
也可以使用下面的方法來觸發內存泄露:
1.在不同Activity狀態時,重復做橫豎屏切換操作。旋轉屏幕可能導致應用泄露 Activity、Context 或 View對象,因為系統會重新創建 Activity,如果應用在其它地方持有這些對象的引用,那麼系統就不能回收它們。
2.在不同Activity狀態時,做切換應用操作(切換到主屏幕,然後回到應用中)。
提示:也可以使用monkey測試來執行上述步驟。想要獲得更多運行 monkey 測試的信息,請查閱 monkeyrunner 文檔。

『叄』 android開發中讓圖片旋轉發生outofmemory錯誤要怎麼解決

沒什麼好辦法,載入Bitmap的時候已經佔用內存了,你一讓它旋轉,它會重新調用OnDraw方法,將界面重新繪制一下,又佔用了一塊內存,沒有思路。要不你試試將圖片縮小一下再試試。

『肆』 如何看android monitor的memory指標

首先檢查是否有root之後的出現的管理許可權,一般情況會在所有程序中有【授權管理】【superuser】這類名稱的圖標。 還有就是通過手機助手進行檢測,比如電腦安裝騰訊手機管家,它就會提示手機是否root,並且是否進行root。比較簡單。

『伍』 android studio中的memory怎麼用

memory可以查看內存的使用情況,來調試軟體界面的影響速度的地方

『陸』 Android 內存溢出怎麼解決

Android 內存溢出的原因和解決方案如下:
1.Android的虛擬機是基於寄存器的Dalvik,它的最大堆大小一般是16M,有的機器為24M.因此我們所能利用的內存空間是有限的.如果我們的內存佔用超過了一定的水平就會出現OutOfMemory的錯誤.原因主要有兩個:
l 由於我們程序的失誤,長期保持某些資源(如Context)的引用,造成內存泄露,資源造成得不到釋放.
l 保存了多個耗用內存過大的對象(如Bitmap),造成內存超出限制.
2. Static
static是Java中的一個關鍵字,當用它來修飾成員變數時,那麼該變數就屬於該類,而不是該類的實例.所以用static修飾的變數,它的生命周期是很長的,如果用它來引用一些資源耗費過多的實例(Context的情況最多)就要謹慎對待了.例如xxx源碼:
public class IntentMapping {
private static Contextcontext;
//. . .
}

『柒』 求助:Android OutOfMemory問題

一般android的內存比較大,如果出現OOM,可能有兩個方面的原因:
1。 代碼質量問題,代碼中有易造成內存泄露的代碼。
2。 Android的棧空間的確不大, 避免過多次數調用遞歸。 如果遞歸過多又無法避免遞歸, 請在遞歸函數體內少生成使用局部變數,臨時變數。

先檢查第2點,如果沒有第2點的情況就好好看看第1點是不是有問題。
樓主的問題我也曾出現過。 原因是我使用的過多的圖片資源沒有及時回收掉,導致內存溢出

『捌』 android studio memory怎麼看

啟動與關閉Memory監測按鈕

手動觸發GC按鈕
mp java heap 按鈕,點擊Android Studio就開始幹活了,成功後會自動打開 hprof文件。
start(stop) allocation tracking按鈕先點擊一次,然後會看到Memory Recorder開始轉動,然後自己開始在APP上面做相應的操作。在合適的時間再點一次,結束記錄。
最後這個問號按鈕,點擊後進入官方介紹文檔。

『玖』 androidstudio 裡面的memory和cpu圖形可以導出來么

j解決方法已找到,是由於AndroidStudio默認設置的原因,只需要Tools——》Android——》Enable ADB Integration選中即可。

熱點內容
ios雲存儲自動訂購 發布:2025-05-20 11:06:22 瀏覽:108
編程與數學 發布:2025-05-20 11:01:23 瀏覽:443
asp連接遠程資料庫 發布:2025-05-20 10:50:20 瀏覽:389
一般電腦配置哪個好 發布:2025-05-20 10:40:58 瀏覽:602
我的世界擼樹伺服器 發布:2025-05-20 10:33:37 瀏覽:740
ftp搭建win7 發布:2025-05-20 10:06:06 瀏覽:82
訪問堅果 發布:2025-05-20 10:06:02 瀏覽:394
ftpxlight 發布:2025-05-20 10:05:22 瀏覽:111
java的實驗報告 發布:2025-05-20 10:02:06 瀏覽:529
豪華配置高電動轎車有哪些 發布:2025-05-20 10:01:59 瀏覽:487