dumpsys
這項工具是在 Android 裝置上執行,可提供系統服務相關資訊。使用以下指令,透過指令列呼叫 dumpsys
Android Debug Bridge (ADB)
,針對在連線裝置上執行的所有系統服務取得診斷輸出。
輸出的內容通常比您預期的還要詳細,因此使用指令列
選項,僅取得系統服務的輸出內容
您期望的行為本頁也會說明如何使用 dumpsys
完成
一般工作,例如檢查輸入、RAM、電池或網路診斷。
語法
使用 dumpsys
的一般語法如下:
adb shell dumpsys [-t timeout] [--help | -l | --skip services | service [arguments] | -c | -h]
如要取得
已連結裝置的所有系統服務,請執行 adb shell dumpsys
。
無論如何,產生的結果量將比您預期的要多。適用對象
更易於管理的輸出內容,方法是加入
並不在指令中舉例來說,以下指令提供系統資料
輸入元件,例如觸控螢幕或內建鍵盤:
adb shell dumpsys input
如需可與 dumpsys
搭配使用的系統服務完整清單,請使用
以下指令:
adb shell dumpsys -l
指令列選項
下表列出使用 dumpsys
時的可用選項:
表 1. 以下項目的可用選項清單: dumpsys
選項 | 說明 |
---|---|
-t timeout
|
指定逾時期間(以秒為單位)。如未指定,預設值為 10 秒。 |
--help
|
輸出 dumpsys 工具的說明文字。
|
-l
|
輸出可搭配系統服務使用的完整清單
dumpsys 。
|
--skip services
|
指定您不想納入的 services 輸出內容 |
service [arguments]
|
指定您想要輸出的 service。部分服務
可讓您傳遞選擇性的 arguments如要瞭解
這些選用引數,請傳送 -h 選項給
服務:
adb shell dumpsys procstats -h |
-c
|
指定特定服務時,請附加這個選項以 這種格式適合機器使用 |
-h
|
附加特定服務的選項,即可查看相關說明文字和該服務的其他選項。 |
檢查輸入診斷資料
指定 input
服務,如下列指令所示,會將
系統輸入裝置的狀態,例如鍵盤和觸控螢幕
處理輸入事件的處理程序
adb shell dumpsys input
輸出結果會因連線裝置上執行的 Android 版本而有所不同。以下各節說明您通常使用的資訊類型 請參閱
事件中心狀態
以下為檢查輸入診斷「事件狀態」時可能看到的示例:
INPUT MANAGER (dumpsys input) Event Hub State: BuiltInKeyboardId: -2 Devices: -1: Virtual Classes: 0x40000023 Path:Descriptor: a718a782d34bc767f4689c232d64d527998ea7fd Location: ControllerNumber: 0 UniqueId: Identifier: bus=0x0000, vendor=0x0000, product=0x0000, version=0x0000 KeyLayoutFile: /system/usr/keylayout/Generic.kl KeyCharacterMapFile: /system/usr/keychars/Virtual.kcm ConfigurationFile: HaveKeyboardLayoutOverlay: false 1: msm8974-taiko-mtp-snd-card Headset Jack Classes: 0x00000080 Path: /dev/input/event5 Descriptor: c8e3782483b4837ead6602e20483c46ff801112c Location: ALSA ControllerNumber: 0 UniqueId: Identifier: bus=0x0000, vendor=0x0000, product=0x0000, version=0x0000 KeyLayoutFile: KeyCharacterMapFile: ConfigurationFile: HaveKeyboardLayoutOverlay: false 2: msm8974-taiko-mtp-snd-card Button Jack Classes: 0x00000001 Path: /dev/input/event4 Descriptor: 96fe62b244c555351ec576b282232e787fb42bab Location: ALSA ControllerNumber: 0 UniqueId: Identifier: bus=0x0000, vendor=0x0000, product=0x0000, version=0x0000 KeyLayoutFile: /system/usr/keylayout/msm8974-taiko-mtp-snd-card_Button_Jack.kl KeyCharacterMapFile: /system/usr/keychars/msm8974-taiko-mtp-snd-card_Button_Jack.kcm ConfigurationFile: HaveKeyboardLayoutOverlay: false 3: hs_detect Classes: 0x00000081 Path: /dev/input/event3 Descriptor: 485d69228e24f5e46da1598745890b214130dbc4 Location: ControllerNumber: 0 UniqueId: Identifier: bus=0x0000, vendor=0x0001, product=0x0001, version=0x0001 KeyLayoutFile: /system/usr/keylayout/hs_detect.kl KeyCharacterMapFile: /system/usr/keychars/hs_detect.kcm ConfigurationFile: HaveKeyboardLayoutOverlay: false ...
輸入閱讀器狀態
InputReader
負責將核心解碼的輸入事件解碼。結果
狀態傾印會顯示每個輸入裝置的設定方式
近期發生的狀態變化,例如按下按鍵或輕觸
可以輕觸或關閉
以下範例顯示觸控螢幕的輸出結果。記下裝置的解析度和使用的校正參數。
Input Reader State ... Device 6: Melfas MMSxxx Touchscreen IsExternal: false Sources: 0x00001002 KeyboardType: 0 Motion Ranges: X: source=0x00001002, min=0.000, max=719.001, flat=0.000, fuzz=0.999 Y: source=0x00001002, min=0.000, max=1279.001, flat=0.000, fuzz=0.999 PRESSURE: source=0x00001002, min=0.000, max=1.000, flat=0.000, fuzz=0.000 SIZE: source=0x00001002, min=0.000, max=1.000, flat=0.000, fuzz=0.000 TOUCH_MAJOR: source=0x00001002, min=0.000, max=1468.605, flat=0.000, fuzz=0.000 TOUCH_MINOR: source=0x00001002, min=0.000, max=1468.605, flat=0.000, fuzz=0.000 TOOL_MAJOR: source=0x00001002, min=0.000, max=1468.605, flat=0.000, fuzz=0.000 TOOL_MINOR: source=0x00001002, min=0.000, max=1468.605, flat=0.000, fuzz=0.000 Touch Input Mapper: Parameters: GestureMode: spots DeviceType: touchScreen AssociatedDisplay: id=0, isExternal=false OrientationAware: true Raw Touch Axes: X: min=0, max=720, flat=0, fuzz=0, resolution=0 Y: min=0, max=1280, flat=0, fuzz=0, resolution=0 Pressure: min=0, max=255, flat=0, fuzz=0, resolution=0 TouchMajor: min=0, max=30, flat=0, fuzz=0, resolution=0 TouchMinor: unknown range ToolMajor: unknown range ToolMinor: unknown range Orientation: unknown range Distance: unknown range TiltX: unknown range TiltY: unknown range TrackingId: min=0, max=65535, flat=0, fuzz=0, resolution=0 Slot: min=0, max=9, flat=0, fuzz=0, resolution=0 Calibration: touch.size.calibration: diameter touch.size.scale: 10.000 touch.size.bias: 0.000 touch.size.isSummed: false touch.pressure.calibration: amplitude touch.pressure.scale: 0.005 touch.orientation.calibration: none touch.distance.calibration: none SurfaceWidth: 720px SurfaceHeight: 1280px SurfaceOrientation: 0 Translation and Scaling Factors: XScale: 0.999 YScale: 0.999 XPrecision: 1.001 YPrecision: 1.001 GeometricScale: 0.999 PressureScale: 0.005 SizeScale: 0.033 OrientationCenter: 0.000 OrientationScale: 0.000 DistanceScale: 0.000 HaveTilt: false TiltXCenter: 0.000 TiltXScale: 0.000 TiltYCenter: 0.000 TiltYScale: 0.000 Last Button State: 0x00000000 Last Raw Touch: pointerCount=0 Last Cooked Touch: pointerCount=0
在輸入讀取器狀態傾印的結尾, 全域設定參數,例如輕觸間隔:
Configuration: ExcludedDeviceNames: [] VirtualKeyQuietTime: 0.0ms PointerVelocityControlParameters: scale=1.000, lowThreshold=500.000, highThreshold=3000.000, acceleration=3.000 WheelVelocityControlParameters: scale=1.000, lowThreshold=15.000, highThreshold=50.000, acceleration=4.000 PointerGesture: Enabled: true QuietInterval: 100.0ms DragMinSwitchSpeed: 50.0px/s TapInterval: 150.0ms TapDragInterval: 300.0ms TapSlop: 20.0px MultitouchSettleInterval: 100.0ms MultitouchMinDistance: 15.0px SwipeTransitionAngleCosine: 0.3 SwipeMaxWidthRatio: 0.2 MovementSpeedRatio: 0.8 ZoomSpeedRatio: 0.3
輸入調度工具狀態
InputDispatcher
負責將輸入事件傳送至應用程式。如下列範例輸出所示,其狀態傾印會顯示
使用者輕觸的視窗、輸入佇列的狀態、是否發生
以及其他輸入事件資訊:
Input Dispatcher State: DispatchEnabled: 1 DispatchFrozen: 0 FocusedApplication: <null> FocusedWindow: name='Window{3fb06dc3 u0 StatusBar}' TouchStates: <no displays touched> Windows: 0: name='Window{357bbbfe u0 SearchPanel}', displayId=0, paused=false, hasFocus=false, hasWallpaper=false, visible=false, canReceiveKeys=false, flags=0x01820100, type=0x000007e8, layer=211000, frame=[0,0][1080,1920], scale=1.000000, touchableRegion=[0,0][1080,1920], inputFeatures=0x00000000, ownerPid=22674, ownerUid=10020, dispatchingTimeout=5000.000ms 1: name='Window{3b14c0ca u0 NavigationBar}', displayId=0, paused=false, hasFocus=false, hasWallpaper=false, visible=false, canReceiveKeys=false, flags=0x01840068, type=0x000007e3, layer=201000, frame=[0,1776][1080,1920], scale=1.000000, touchableRegion=[0,1776][1080,1920], inputFeatures=0x00000000, ownerPid=22674, ownerUid=10020, dispatchingTimeout=5000.000ms 2: name='Window{2c7e849c u0 com.vito.lux}', displayId=0, paused=false, hasFocus=false, hasWallpaper=false, visible=true, canReceiveKeys=false, flags=0x0089031a, type=0x000007d6, layer=191000, frame=[-495,-147][1575,1923], scale=1.000000, touchableRegion=[-495,-147][1575,1923], inputFeatures=0x00000000, ownerPid=4697, ownerUid=10084, dispatchingTimeout=5000.000ms ... MonitoringChannels: 0: 'WindowManager (server)' RecentQueue: length=10 MotionEvent(deviceId=4, source=0x00001002, action=2, flags=0x00000000, metaState=0x00000000, buttonState=0x00000000, edgeFlags=0x00000000, xPrecision=1.0, yPrecision=1.0, displayId=0, pointers=[0: (335.0, 1465.0)]), policyFlags=0x62000000, age=217264.0ms MotionEvent(deviceId=4, source=0x00001002, action=1, flags=0x00000000, metaState=0x00000000, buttonState=0x00000000, edgeFlags=0x00000000, xPrecision=1.0, yPrecision=1.0, displayId=0, pointers=[0: (335.0, 1465.0)]), policyFlags=0x62000000, age=217255.7ms MotionEvent(deviceId=4, source=0x00001002, action=0, flags=0x00000000, metaState=0x00000000, buttonState=0x00000000, edgeFlags=0x00000000, xPrecision=1.0, yPrecision=1.0, displayId=0, pointers=[0: (330.0, 1283.0)]), policyFlags=0x62000000, age=216805.0ms ... PendingEvent: <none> InboundQueue: <empty> ReplacedKeys: <empty> Connections: 0: channelName='WindowManager (server)', windowName='monitor', status=NORMAL, monitor=true, inputPublisherBlocked=false OutboundQueue: <empty> WaitQueue: <empty> 1: channelName='278c1d65 KeyguardScrim (server)', windowName='Window{278c1d65 u0 KeyguardScrim}', status=NORMAL, monitor=false, inputPublisherBlocked=false OutboundQueue: <empty> WaitQueue: <empty> 2: channelName='357bbbfe SearchPanel (server)', windowName='Window{357bbbfe u0 SearchPanel}', status=NORMAL, monitor=false, inputPublisherBlocked=false OutboundQueue: <empty> WaitQueue: <empty> ... AppSwitch: not pending 7: channelName='2280455f com.google.android.gm/com.google.android.gm.ConversationListActivityGmail (server)', windowName='Window{2280455f u0 com.google.android.gm/com.google.android.gm.ConversationListActivityGmail}', status=NORMAL, monitor=false, inputPublisherBlocked=false OutboundQueue: <empty> WaitQueue: <empty> 8: channelName='1a7be08a com.android.systemui/com.android.systemui.recents.RecentsActivity (server)', windowName='Window{1a7be08a u0 com.android.systemui/com.android.systemui.recents.RecentsActivity EXITING}', status=NORMAL, monitor=false, inputPublisherBlocked=false OutboundQueue: <empty> WaitQueue: <empty> 9: channelName='3b14c0ca NavigationBar (server)', windowName='Window{3b14c0ca u0 NavigationBar}', status=NORMAL, monitor=false, inputPublisherBlocked=false OutboundQueue: <empty> WaitQueue: <empty> ... Configuration: KeyRepeatDelay: 50.0ms KeyRepeatTimeout: 500.0ms
檢查事項
檢查輸出內容時,請注意以下幾點
對 input
服務執行定義:
事件中心狀態:
- 顯示了所有預期的輸入裝置。
- 每部輸入裝置都有合適的金鑰版面配置檔案、金鑰字元對應檔案和輸入裝置設定設定檔。如果檔案遺失或其中 就不會載入這些語法
- 每部輸入裝置都已正確分類。
Classes
檔案中的位元會對應到EventHub.h
中的旗標,例如INPUT_DEVICE_CLASS_TOUCH_MT
。 -
BuiltInKeyboardId
是正確的。如果裝置不支援 使用內建鍵盤,則 ID 必須是-2
。否則, 應為內建鍵盤的 ID。 - 如果您觀察到
BuiltInKeyboardId
並非-2
,但應該正確,那麼您缺少索引鍵字元對應 檔案導入特殊功能鍵盤特殊功能撥號鍵盤 裝置應含有僅含有type SPECIAL_FUNCTION
。
輸入閱讀器狀態:
- 顯示了所有預期的輸入裝置。
- 每部輸入裝置設定皆正確無誤。請特別留意觸控螢幕和搖桿是否正確無誤。
輸入調度工具狀態:
- 所有輸入事件都會照常處理。
- 同時輕觸觸控螢幕並執行
dumpsys
後, 的TouchStates
行可正確識別您觸碰的視窗。
測試 UI 效能
指定 gfxinfo
服務可提供效能資訊的輸出內容
與錄製階段期間發生的動畫影格相關
下列指令使用 gfxinfo
收集特定套件名稱的 UI 效能資料:
adb shell dumpsys gfxinfo package-name
您也可以加入 framestats
選項,提供更詳細的影格
提供近期影格的時間資訊
問題更準確:
adb shell dumpsys gfxinfo package-name framestats
如要進一步瞭解如何使用 gfxinfo
和 framestats
整合 UI
測試您的測試方式的效果,請參閱
編寫 Macrobenchmark。
檢查網路診斷
指定 netstats
服務即可取得系統收集的網路使用統計資料
。為了輸出其他資訊,
詳細的不重複使用者 ID (UID) 資訊,請加入 detail
選項,如
如下:
adb shell dumpsys netstats detail
輸出結果會因連線裝置上執行的 Android 版本而有所不同。以下各節說明您通常使用的資訊類型 請參閱
使用中的介面和有效的 UID 介面
下列範例輸出會列出使用中的介面和有效的 UID 連結裝置的介面在大多數情況下, 介面和使用中的 UID 介面相同。
Active interfaces: iface=wlan0 ident=[{type=WIFI, subType=COMBINED, networkId="Guest"}] Active UID interfaces: iface=wlan0 ident=[{type=WIFI, subType=COMBINED, networkId="Guest"}]
開發人員和「Xt」統計資料
以下是開發人員統計資料部分的輸出範例:
Dev stats: Pending bytes: 1798112 History since boot: ident=[{type=WIFI, subType=COMBINED, networkId="Guest", metered=false}] uid=-1 set=ALL tag=0x0 NetworkStatsHistory: bucketDuration=3600 st=1497891600 rb=1220280 rp=1573 tb=309870 tp=1271 op=0 st=1497895200 rb=29733 rp=145 tb=85354 tp=185 op=0 st=1497898800 rb=46784 rp=162 tb=42531 tp=192 op=0 st=1497902400 rb=27570 rp=111 tb=35990 tp=121 op=0 Xt stats: Pending bytes: 1771782 History since boot: ident=[{type=WIFI, subType=COMBINED, networkId="Guest", metered=false}] uid=-1 set=ALL tag=0x0 NetworkStatsHistory: bucketDuration=3600 st=1497891600 rb=1219598 rp=1557 tb=291628 tp=1255 op=0 st=1497895200 rb=29623 rp=142 tb=82699 tp=182 op=0 st=1497898800 rb=46684 rp=160 tb=39756 tp=191 op=0 st=1497902400 rb=27528 rp=110 tb=34266 tp=120 op=0
UID 統計資料
以下是每個 UID 的詳細統計資料範例:
UID stats: Pending bytes: 744 Complete history: ident=[[type=MOBILE_SUPL, subType=COMBINED, subscriberId=311111...], [type=MOBILE, subType=COMBINED, subscriberId=311111...]] uid=10007 set=DEFAULT tag=0x0 NetworkStatsHistory: bucketDuration=7200000 bucketStart=1406167200000 activeTime=7200000 rxBytes=4666 rxPackets=7 txBytes=1597 txPackets=10 operations=0 ident=[[type=WIFI, subType=COMBINED, networkId="MySSID"]] uid=10007 set=DEFAULT tag=0x0 NetworkStatsHistory: bucketDuration=7200000 bucketStart=1406138400000 activeTime=7200000 rxBytes=17086802 rxPackets=15387 txBytes=1214969 txPackets=8036 operations=28 bucketStart=1406145600000 activeTime=7200000 rxBytes=2396424 rxPackets=2946 txBytes=464372 txPackets=2609 operations=70 bucketStart=1406152800000 activeTime=7200000 rxBytes=200907 rxPackets=606 txBytes=187418 txPackets=739 operations=0 bucketStart=1406160000000 activeTime=7200000 rxBytes=826017 rxPackets=1126 txBytes=267342 txPackets=1175 operations=35
如要找出應用程式的 UID,請執行下列指令:adb shell dumpsys
package your-package-name
。然後找出標有 userId
的行。
舉例來說,如要找出應用程式的網路用量「com.example.myapp」,請執行 以下指令:
adb shell dumpsys package com.example.myapp | grep userId
輸出應該會類似以下的內容:
userId=10007 gids=[3003, 1028, 1015]
使用上述的傾印範例,找出含有 uid=10007
的行。兩個
線條存在—第一行代表行動連線,第二行代表
Wi-Fi 連線。您可以在每一行的下方查看下列資訊:
每個兩小時間隔,bucketDuration
以毫秒為單位:
-
set=DEFAULT
表示前景網路用量,set=BACKGROUND
則表示背景用量。set=ALL
表示兩者。 -
tag=0x0
表示與流量相關聯的通訊端標記。 -
rxBytes
和rxPackets
代表對應時間間隔內接收的位元組數和收到的封包。 -
txBytes
和txPackets
代表在對應的時間間隔內傳送 (已傳送) 位元組和已傳送封包。
檢查電池診斷
指定 batterystats
服務會產生統計資料資料
依不重複使用者 ID (UID) 分類的裝置電池用量。如要瞭解操作方式
使用 dumpsys
測試應用程式的打盹和應用程式待命功能。請參閱
使用打盹和應用程式待命功能進行測試。
batterystats
的指令如下:
adb shell dumpsys batterystats options
如要查看 batterystats
可用的其他選項,請納入 -h
選項。以下範例會輸出
自裝置上次充電後指定的應用程式套件:
adb shell dumpsys batterystats --charged package-name
輸出結果通常包含以下內容:
- 電池相關事件記錄
- 裝置的全域統計資料
- 每個 UID 和系統元件的概略耗電量
- 每個封包每個應用程式的行動毫秒數
- 系統 UID 匯總統計資料
- 應用程式 UID 匯總統計資料
如要進一步瞭解如何使用 batterystats
及產生 HTML 視覺呈現,
輸出資料,方便你瞭解及診斷電池相關
問題,請參閱「使用 Batterystats 和 Battery Historian 剖析電池用量」。
檢查易於機器使用的輸出
您可以使用以下程式碼,產生機器可讀取的 CSV 格式的 batterystats
輸出內容:
以下指令:
adb shell dumpsys batterystats --checkin
以下為輸出範例:
9,0,i,vers,11,116,K,L 9,0,i,uid,1000,android 9,0,i,uid,1000,com.android.providers.settings 9,0,i,uid,1000,com.android.inputdevices 9,0,i,uid,1000,com.android.server.telecom ... 9,0,i,dsd,1820451,97,s-,p- 9,0,i,dsd,3517481,98,s-,p- 9,0,l,bt,0,8548446,1000983,8566645,1019182,1418672206045,8541652,994188 9,0,l,gn,0,0,666932,495312,0,0,2104,1444 9,0,l,m,6794,0,8548446,8548446,0,0,0,666932,495312,0,697728,0,0,0,5797,0,0 ...
電池用量的觀察結果可能是依照 UID 或系統層級。已為以下應用程式選取資料: 所納入的包容性。每一列 代表觀察,包含下列元素:
- 預留位置整數
- 與觀察項目相關聯的 User-ID
- 匯總模式:
i
與充電/未充電狀態不相關的資訊。--charged
的l
(自上次充電後的使用情形)。--unplugged
的u
(自上次拔除電源後至今的使用情形)。將在 Android 5.1.1 版中淘汰。
- 區段 ID:決定如何解譯行中的後續值。
下表說明各種可能出現的區段 ID:
表 2. 區段 ID 清單
版面 ID | 說明 | 其餘欄位 |
---|---|---|
|
版本 |
|
|
UID |
|
|
APK |
|
|
程序 |
|
|
感應器 |
|
|
振子 |
|
|
前景 |
|
|
狀態時間 |
|
|
Wake Lock |
|
|
同步 |
|
|
工作 |
|
|
核心 Wake Lock |
|
|
喚醒原因 |
|
|
網路 |
|
|
使用者活動 |
|
|
電池 |
|
|
電池放電 |
|
|
電量 |
|
|
Wi-Fi |
|
|
全球 Wi-Fi |
|
|
全域藍牙 |
|
|
其他 |
|
|
全球網路 |
|
|
螢幕亮度 |
|
|
訊號掃描時間 |
|
|
訊號強度強度 |
|
|
訊號強度數 |
|
|
數據連線時間 |
|
|
數據連線數量 |
|
|
Wi-Fi 狀態時間 |
|
|
Wi-Fi 狀態數量 |
|
|
Wi-Fi 供應狀態時間 |
|
|
Wi-Fi 供應鏈狀態 |
|
|
Wi-Fi 訊號強度 |
|
|
Wi-Fi 訊號強度 |
|
|
藍牙狀態時間 |
|
|
藍牙狀態數量 |
|
|
用電量摘要 |
|
|
電力使用物品 |
|
|
放電步驟 |
|
|
充電步驟 |
|
|
剩餘放電時間 |
|
|
剩餘充電時間 |
|
注意:在 Android 6.0 以下版本中,
m
(其他) 追蹤了藍牙無線電、行動網路無線電和 Wi-Fi
版面類別在 Android 6.0 以上版本中,這些元件的耗電量:
透過 pwi
(電力使用物品) 部分追蹤,附有個別標籤
(wifi
、blue
、cell
)。
查看記憶體配置
您可以透過下列兩種方式檢查應用程式的記憶體用量:
使用 procstats
,或是在特定時間點使用 meminfo
。
以下說明如何使用這兩種方法。
追蹤記錄
procstats
可讓您查看應用程式的長期行為
包括檔案在背景執行的時間長度,以及
結果。可快速找出
可能會影響應用程式效能
也就是在低記憶體裝置上運作的應用程式其狀態傾印
應用程式的執行階段、比例集大小 (PSS)、不重複集大小 (USS) 和
常駐集大小 (RSS)。
如要取得過去三小時的應用程式記憶體用量統計資料,請使用使用者可理解的格式,執行下列指令:
adb shell dumpsys procstats --hours 3
如以下範例所示,輸出結果會顯示
以及 PSS、USS 和 RSS
超過 minPSS-avgPSS-maxPSS/minUSS-avgUSS-maxUSS/minRSS-avgRSS-maxRSS
以及樣本數
AGGREGATED OVER LAST 3 HOURS: * com.android.systemui / u0a37 / v28: TOTAL: 100% (15MB-16MB-17MB/7.7MB-8.7MB-9.4MB/7.7MB-9.6MB-84MB over 178) Persistent: 100% (15MB-16MB-17MB/7.7MB-8.7MB-9.4MB/7.7MB-9.6MB-84MB over 178) * com.android.se / 1068 / v28: TOTAL: 100% (2.8MB-2.9MB-2.9MB/300KB-301KB-304KB/304KB-22MB-33MB over 3) Persistent: 100% (2.8MB-2.9MB-2.9MB/300KB-301KB-304KB/304KB-22MB-33MB over 3) * com.google.android.gms.persistent / u0a7 / v19056073: TOTAL: 100% (37MB-38MB-40MB/27MB-28MB-29MB/124MB-125MB-126MB over 2) Imp Fg: 100% (37MB-38MB-40MB/27MB-28MB-29MB/124MB-125MB-126MB over 2) ... * com.android.gallery3d / u0a62 / v40030: TOTAL: 0.01% Receiver: 0.01% (Cached): 54% (6.4MB-6.5MB-6.9MB/4.4MB-4.4MB-4.4MB/4.4MB-26MB-68MB over 6) * com.google.android.tvlauncher / u0a30 / v1010900130: TOTAL: 0.01% Receiver: 0.01% (Cached): 91% (5.8MB-13MB-14MB/3.5MB-10MB-12MB/12MB-33MB-78MB over 6) * com.android.vending:instant_app_installer / u0a16 / v81633968: TOTAL: 0.01% Receiver: 0.01% (Cached): 100% (14MB-15MB-16MB/3.8MB-4.2MB-5.1MB/3.8MB-30MB-95MB over 7) ... Run time Stats: SOff/Norm: +32m52s226ms SOn /Norm: +2h10m8s364ms Mod : +17s930ms TOTAL: +2h43m18s520ms Memory usage: Kernel : 265MB (38 samples) Native : 73MB (38 samples) Persist: 262MB (90 samples) Top : 190MB (325 samples) ImpFg : 204MB (569 samples) ImpBg : 754KB (345 samples) Service: 93MB (1912 samples) Receivr: 227KB (1169 samples) Home : 66MB (12 samples) LastAct: 30MB (255 samples) CchAct : 220MB (450 samples) CchCAct: 193MB (71 samples) CchEmty: 182MB (652 samples) Cached : 58MB (38 samples) Free : 60MB (38 samples) TOTAL : 1.9GB ServRst: 50KB (278 samples) Start time: 2015-04-08 13:44:18 Total elapsed time: +2h43m18s521ms (partial) libart.so
meminfo
您可以錄製應用程式記憶體快照的數據匯報 用來區分不同的 RAM 分配類型 以下指令:
adb shell dumpsys meminfo package_name|pid [-d]
-d
旗標會顯示關於 Dalvik 和 ART 記憶體用量的詳細資訊。
輸出結果會列出應用程式目前的所有配置情形 (以 KB
檢查這類資訊時,您應該熟悉下列類型的分配方式:
- 私有(乾淨頁與臟頁)RAM
- 請注意,這項資料僅有你處理的程序。因為 系統可在應用程式的程序銷毀時恢復的 RAM 容量。 一般來說,這個環節最重要的部分是 Private Dirty RAM。 是最昂貴的,因為它只會用於您的程序,而且 內容只存在於 RAM 中,因此無法分頁至儲存空間,因為 Android 不提供 請使用替換功能您所做的 Dalvik 和原生堆積分配量為 私有的髒汙 RAM。與 Zygote 程序共用的 Dalvik 和原生分配 骯髒的 RAM
- 比例集大小 (PSS)
- 這是應用程式 RAM 用量的測量結果,會將帳戶分享情況納入考量 用於不同程序的網頁任何直接識別程序專用的 RAM 頁面 提升 PSS 價值,同時與其他程序共用的頁面 只會根據共用量比例計算 PSS 值。適用對象 舉例來說,如果兩個程序共用某個網頁,這將佔據一半大小的一半。 各程序的 PSS。
評估 PSS 的一大優點是,您可以將 PSS 相加 所有程序來決定所有程序使用的實際記憶體。這個 表示 PSS 是程序實際 RAM 權重的理想指標, 比較基準與其他程序的 RAM 用量 RAM。
舉例來說,以下是 Google 地圖程序在 Nexus 5 上的輸出內容 裝置:
adb shell dumpsys meminfo com.google.android.apps.maps -d
注意:您所看到的資訊可能會與 但因為某些輸出內容會因平台而異 版本。
** MEMINFO in pid 18227 [com.google.android.apps.maps] ** Pss Private Private Swapped Heap Heap Heap Total Dirty Clean Dirty Size Alloc Free ------ ------ ------ ------ ------ ------ ------ Native Heap 10468 10408 0 0 20480 14462 6017 Dalvik Heap 34340 33816 0 0 62436 53883 8553 Dalvik Other 972 972 0 0 Stack 1144 1144 0 0 Gfx dev 35300 35300 0 0 Other dev 5 0 4 0 .so mmap 1943 504 188 0 .apk mmap 598 0 136 0 .ttf mmap 134 0 68 0 .dex mmap 3908 0 3904 0 .oat mmap 1344 0 56 0 .art mmap 2037 1784 28 0 Other mmap 30 4 0 0 EGL mtrack 73072 73072 0 0 GL mtrack 51044 51044 0 0 Unknown 185 184 0 0 TOTAL 216524 208232 4384 0 82916 68345 14570 Dalvik Details .Heap 6568 6568 0 0 .LOS 24771 24404 0 0 .GC 500 500 0 0 .JITCache 428 428 0 0 .Zygote 1093 936 0 0 .NonMoving 1908 1908 0 0 .IndirectRef 44 44 0 0 Objects Views: 90 ViewRootImpl: 1 AppContexts: 4 Activities: 1 Assets: 2 AssetManagers: 2 Local Binders: 21 Proxy Binders: 28 Parcel memory: 18 Parcel count: 74 Death Recipients: 2 OpenSSL Sockets: 2
以下是 Gmail 應用程式 Dalvik 中的舊版 dumpsys
:
** 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 配置使用的 RAM。
Pss Total
包含所有 Zygote 分配,並依據其在不同程序間的共享程度加權, 如 PSS 定義中所述。Private Dirty
數字是 實際 RAM 僅適用於應用程式堆積,包括您自己的配置 以及自分解應用程式 來自 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
- 對應
.so
(原生) 和.dex
(Dalvik 或 ART) 代碼。Pss Total
號碼 包含跨應用程式共用的平台程式碼。Private Clean
是 導入應用程式的程式碼一般來說,實際的對應大小會比較大。這裡的 RAM 只是現在需要用到 RAM 來執行 應用程式。不過,.so mmap
有很大的私密髒汙,這是為了進行修正 加到原生程式碼的最終地址中 .oat mmap
- 這是程式碼映像檔使用的 RAM 用量。此設定根據 多個應用程式常用的預先載入類別。已分享這張圖片 且不會受特定應用程式影響。
.art mmap
- 這是堆積映像檔使用的 RAM 用量。此設定根據
多個應用程式常用的預先載入類別。這張圖片會顯示在下列服務中:
且不會受特定應用程式影響。雖然 ART 圖片
包含「
Object
」 就不會計入堆積大小 .Heap
(僅限帶有-d
旗標)- 這是應用程式的堆積記憶體大小。這不包含 圖像和大型物件空間,但包含 Zygote 的空間和未移動的空間 空白鍵。
.LOS
(僅限帶有-d
旗標)- 這是 ART 大型物件空間使用的 RAM 容量。這包括 Zygote 的大型物件。大型物件是所有的原始陣列配置都較大 大於 12 KB
.GC
(僅限帶有-d
旗標)- 這是垃圾收集的營運成本。由於沒有 能夠減輕負擔
.JITCache
(僅限帶有-d
旗標)- 這是 JIT 資料和程式碼快取使用的記憶體量。 由於所有的應用程式在安裝時都會編譯,因此通常為 0 讓應用程式從可以最快做出回應的位置 回應使用者要求
.Zygote
(僅限帶有-d
旗標)- 這是 Zygote 空間使用的記憶體用量。Zygote 的太空世界 且絕對不會分配。
.NonMoving
(僅限帶有-d
旗標)- 這是指 ART 非移動空間所使用的 RAM 容量。未移動 空間包含特殊的非移動物件,例如欄位和方法。你可以 減少在應用程式中使用較少的欄位和方法,藉此減少這個部分。 ,瞭解如何調查及移除這項存取權。
.IndirectRef
(僅限帶有-d
旗標)- 此為 ART 間接參考表格使用的 RAM 用量。 通常這個金額很小,不過如果金額太高,或許可以 會減少本機和全域 JNI 參照的數量,藉此減少作業數量。
Unknown
- 任何無法歸類到其他項目的 RAM 頁面
特定項目目前這部分主要包含原生分配設定
在收集這項資料時,工具會根據位址空間版面配置判斷
隨機化 (ASLR)。就像 Dalvik 堆積一樣,
Pss Total
的Unknown
會將與 Zygote 和Private Dirty
共用的帳戶納入考量 只有您的應用程式專用的不明 RAM。 TOTAL
- 程序使用的總比例集 (PSS) RAM 總數。這是
所有 PSS 欄位的總和它代表的是
讓您能直接與其他程序
可用的 RAM。
共有
Private Dirty
和Private Clean
不會與其他程序共用 程序刪除後,這些配置中的所有 RAM 都會釋出 返回系統。也可以將Private Clean
分頁移出並釋放 容器才會刪除,但Private Dirty
只會 再發布。骯髒的 RAM 網頁經過修改,因此必須留在 RAM 環境中 也不必切換Clean RAM 是指對應到永久檔案的網頁,例如 執行這些動作,如果已有一段時間就不需使用,可將其清除。
ViewRootImpl
- 在程序中正在使用的根資料檢視次數。每個根層級檢視畫面 幫助您找出與視窗相關的記憶體流失情形 對話方塊或其他視窗
AppContexts
和Activities
- 應用程式數量
Context
和Activity
物件中目前存放在處理程序中的 物件。這麼做可讓您快速 找出無法進行垃圾收集的Activity
物件 而產生的內容是很常見的情況這些物件通常會 因而能有效追蹤這些委刊項 導致大量記憶體流失 ,瞭解如何調查及移除這項存取權。