dumpsys ابزاری است که روی دستگاههای اندروید اجرا میشود و اطلاعاتی در مورد سرویسهای سیستم ارائه میدهد. dumpsys از خط فرمان با استفاده از Android Debug Bridge (ADB) فراخوانی کنید تا خروجی تشخیصی برای همه سرویسهای سیستمی که روی یک دستگاه متصل اجرا میشوند، دریافت کنید.
این خروجی معمولاً طولانیتر از آن چیزی است که شما میخواهید، بنابراین از گزینههای خط فرمان در این صفحه استفاده کنید تا فقط خروجی سرویسهای سیستمی مورد نظر خود را دریافت کنید. این صفحه همچنین نحوه استفاده از dumpsys را برای انجام کارهای رایج، مانند بررسی ورودی، رم، باتری یا تشخیص شبکه، شرح میدهد.
نحو
سینتکس کلی استفاده از 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 | مدت زمان وقفه را بر حسب ثانیه مشخص کنید. در صورت عدم تعیین، مقدار پیشفرض ۱۰ ثانیه است. |
--help | متن راهنما را برای ابزار dumpsys چاپ کنید. |
-l | لیست کاملی از سرویسهای سیستمی که میتوانید با dumpsys استفاده کنید را نمایش میدهد. |
--skip services | services را که نمیخواهید در خروجی لحاظ شوند، مشخص کنید. |
service [ arguments ] | service را که میخواهید خروجی آن را نمایش دهید، مشخص کنید. برخی از سرویسها ممکن است به شما اجازه دهند arguments اختیاری ارسال کنید. برای آشنایی با این آرگومانهای اختیاری، گزینه -h را به سرویس ارسال کنید:
adb shell dumpsys procstats -h
|
-c | هنگام مشخص کردن سرویسهای خاص، این گزینه را برای خروجی دادهها در قالبی سازگار با دستگاه اضافه کنید. |
-h | برای برخی از خدمات، این گزینه را اضافه کنید تا متن راهنما و گزینههای اضافی برای آن سرویس را مشاهده کنید. |
بررسی عیبیابی ورودی
مشخص کردن سرویس input ، همانطور که در دستور زیر نشان داده شده است، وضعیت دستگاههای ورودی سیستم مانند صفحه کلید و صفحه لمسی و پردازش رویدادهای ورودی را نمایش میدهد.
adb shell dumpsys input
خروجی بسته به نسخه اندروید در حال اجرا روی دستگاه متصل متفاوت است. بخشهای زیر نوع اطلاعاتی را که معمولاً مشاهده میکنید شرح میدهند.
وضعیت مرکز رویداد
در زیر نمونهای از آنچه ممکن است هنگام بررسی وضعیت Event Hub از ورودیهای تشخیصی مشاهده کنید، آمده است:
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 مسئول ارسال رویدادهای ورودی به برنامهها است. همانطور که در نمونه خروجی زیر نشان داده شده است، خروجی وضعیت آن اطلاعاتی در مورد اینکه کدام پنجره لمس میشود، وضعیت صف ورودی، اینکه آیا ANR در حال انجام است یا خیر و سایر اطلاعات رویداد ورودی را نشان میدهد:
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صحیح است. اگر دستگاه صفحه کلید داخلی ندارد، شناسه باید-2باشد. در غیر این صورت، باید شناسه صفحه کلید داخلی باشد. - اگر مشاهده کردید که
BuiltInKeyboardIdبرابر-2نیست، در حالی که باید باشد، پس شما یک فایل نگاشت کاراکتر کلید برای یک صفحه کلید با عملکرد ویژه را از دست دادهاید. دستگاههای صفحه کلید با عملکرد ویژه باید فایلهای نگاشت کاراکتر کلید داشته باشند که فقط شاملtype SPECIAL_FUNCTIONباشند.
وضعیت خواننده ورودی:
- تمام دستگاههای ورودی مورد انتظار وجود دارند.
- هر دستگاه ورودی به درستی پیکربندی شده است. به طور خاص، بررسی کنید که صفحه لمسی و محورهای جویاستیک درست باشند.
وضعیت توزیعکننده ورودی:
- تمام رویدادهای ورودی مطابق انتظار پردازش میشوند.
- پس از لمس صفحه لمسی و اجرای همزمان
dumpsys، خطTouchStatesبه درستی پنجرهای را که لمس میکنید شناسایی میکند.
تست عملکرد رابط کاربری
مشخص کردن سرویس gfxinfo خروجیای با اطلاعات عملکردی مربوط به فریمهای انیمیشن که در طول مرحله ضبط رخ میدهند، ارائه میدهد. دستور زیر gfxinfo برای جمعآوری دادههای عملکرد رابط کاربری برای یک نام بسته مشخص شده استفاده میکند:
adb shell dumpsys gfxinfo package-name
همچنین میتوانید گزینه framestats را برای ارائه اطلاعات زمانبندی فریم دقیقتر از فریمهای اخیر اضافه کنید تا بتوانید مشکلات را با دقت بیشتری پیگیری و اشکالزدایی کنید:
adb shell dumpsys gfxinfo package-name framestats
برای کسب اطلاعات بیشتر در مورد استفاده از gfxinfo و framestats برای ادغام اندازهگیریهای عملکرد رابط کاربری در شیوههای تست خود، به نوشتن یک Macrobenchmark مراجعه کنید.
بررسی عیبیابی شبکه
مشخص کردن سرویس netstats آمار استفاده از شبکه را که از زمان بوت شدن دستگاه قبلی جمعآوری شده است، ارائه میدهد. برای نمایش اطلاعات اضافی، مانند اطلاعات دقیق شناسه کاربری منحصر به فرد (UID)، گزینه detail را به صورت زیر وارد کنید:
adb shell dumpsys netstats detail
خروجی بسته به نسخه اندروید در حال اجرا روی دستگاه متصل متفاوت است. بخشهای زیر نوع اطلاعاتی را که معمولاً مشاهده میکنید شرح میدهند.
رابطهای فعال و رابطهای فعال 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 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 دارند. دو خط از این نوع وجود دارد - اولی نشان دهندهی اتصال موبایل و دومی نشان دهندهی اتصال وای فای است. در زیر هر خط، میتوانید اطلاعات زیر را برای هر پنجرهی دو ساعته مشاهده کنید که bucketDuration آن را بر حسب میلی ثانیه مشخص میکند:
-
set=DEFAULTنشاندهندهی استفاده از شبکه در پیشزمینه است، در حالی کهset=BACKGROUNDنشاندهندهی استفاده در پسزمینه است.set=ALLنشاندهندهی هر دو است. -
tag=0x0نشان دهنده تگ سوکت مرتبط با ترافیک است. -
rxBytesوrxPacketsنشان دهنده بایتهای دریافتی و بستههای دریافتی در بازه زمانی مربوطه هستند. -
txBytesوtxPacketsنشان دهنده بایتهای ارسالی (منتقل شده) و بستههای ارسالی در بازه زمانی مربوطه هستند.
عیبیابی باتری را بررسی کنید
مشخص کردن سرویس batterystats دادههای آماری در مورد مصرف باتری در یک دستگاه تولید میکند که بر اساس شناسه کاربری منحصر به فرد (UID) سازماندهی شده است. برای یادگیری نحوه استفاده از dumpsys برای آزمایش برنامه خود برای Doze و App Standby، به Testing with Doze and App Standby مراجعه کنید.
دستور مربوط به batterystats به شرح زیر است:
adb shell dumpsys batterystats options
برای مشاهده لیستی از گزینههای اضافی موجود برای batterystats ، گزینه -h را اضافه کنید. مثال زیر آمار مصرف باتری را برای یک بسته برنامه مشخص شده از آخرین باری که دستگاه شارژ شده است، نمایش میدهد:
adb shell dumpsys batterystats --charged package-name
خروجی معمولاً شامل موارد زیر است:
- تاریخچه رویدادهای مرتبط با باتری
- آمار جهانی برای دستگاه
- مصرف تقریبی برق به ازای هر شناسه کاربری (UID) و اجزای سیستم
- میلیثانیههای موبایل به ازای هر برنامه به ازای هر بسته
- آمار تجمیعشدهی شناسهی کاربری سیستم
- آمار تجمیعشدهی شناسهی کاربری برنامه
برای کسب اطلاعات بیشتر در مورد استفاده از batterystats و ایجاد یک تجسم HTML از خروجی، که درک و تشخیص مشکلات مربوط به باتری را آسانتر میکند، Profile battery usage with Batterystats و Battery Historian را مطالعه کنید.
خروجی مناسب برای ماشین را بررسی کنید
با استفاده از دستور زیر میتوانید خروجی batterystats را با فرمت CSV قابل خواندن توسط ماشین تولید کنید:
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) یا سطح سیستم باشد. دادهها بر اساس مفید بودنشان در تحلیل عملکرد باتری برای گنجاندن انتخاب میشوند. هر ردیف نشاندهنده یک مشاهده است که شامل عناصر زیر است:
- یک عدد صحیح جایگزین
- شناسه کاربری مرتبط با مشاهده
- حالت تجمیع:
-
iبرای اطلاعاتی که به وضعیت شارژ/عدم شارژ مربوط نمیشود، مراجعه میکنم. -
lبرای--charged(میزان مصرف از آخرین شارژ). -
uبرای--unplugged(میزان استفاده از آخرین باری که از برق کشیده شده). در اندروید ۵.۱.۱ منسوخ شده است.
-
- شناسه بخش، که نحوه تفسیر مقادیر بعدی در خط را تعیین میکند.
جدول زیر شناسههای مختلف بخش را که ممکن است ببینید، شرح میدهد:
جدول ۲. فهرست شناسههای بخش
| شناسه بخش | توضیحات | فیلدهای باقی مانده |
|---|---|---|
| نسخه | |
| شناسه کاربری | |
| APK | |
| فرآیند | |
| سنسور | |
| ویبراتور | |
| پیشزمینه | |
| زمان ایالت | |
| قفل بیدارباش | |
| همگامسازی | |
| شغل | |
| قفل بیدار شدن هسته | |
| دلیل بیدار شدن | |
| شبکه | |
| فعالیت کاربر | |
| باتری | |
| تخلیه باتری | |
| سطح باتری | |
| وایفای | |
| وایفای جهانی | |
| بلوتوث جهانی | |
| متفرقه | |
| شبکه جهانی | |
| روشنایی صفحه نمایش | |
| زمان اسکن سیگنال | |
| زمان قدرت سیگنال | |
| شمارش قدرت سیگنال | |
| زمان اتصال داده | |
| تعداد اتصال داده | |
| زمان وضعیت وایفای | |
| شمارش وضعیت وایفای | |
| زمان وضعیت درخواستکننده وایفای | |
| شمارش وضعیت درخواستکننده وایفای | |
| زمان قدرت سیگنال Wi-Fi | |
| شمارش قدرت سیگنال وایفای | |
| زمان وضعیت بلوتوث | |
| شمارش وضعیت بلوتوث | |
| خلاصه مصرف برق | |
| مورد استفاده از برق | |
| مرحله تخلیه | |
| مرحله شارژ | |
| زمان تخلیه باقی مانده | |
| زمان شارژ باقی مانده | |
توجه : قبل از اندروید ۶.۰، مصرف برق برای رادیو بلوتوث، رادیو تلفن همراه و وایفای در بخش m (متفرقه) ردیابی میشد. در اندروید ۶.۰ و بالاتر، مصرف برق برای این اجزا در بخش 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
ممینفو
شما میتوانید با دستور زیر، تصویری از نحوهی تقسیم حافظهی برنامهی خود بین انواع مختلف تخصیص رم ثبت کنید:
adb shell dumpsys meminfo [-d] package_name|pid
آپشن -d اطلاعات بیشتری در مورد میزان استفاده از حافظه Dalvik و ART و آپشن -h تمام آپشنهای پشتیبانی شده را نمایش میدهد.
خروجی، تمام تخصیصهای فعلی برنامه شما را که بر حسب کیلوبایت اندازهگیری شدهاند، فهرست میکند.
هنگام بررسی این اطلاعات، باید با انواع تخصیص زیر آشنا باشید:
- رم خصوصی تمیز و کثیف
- این حافظهای است که فقط توسط فرآیند شما استفاده میشود. این بخش عمدهای از رم است که سیستم میتواند هنگام از بین رفتن فرآیند برنامه شما، آن را پس بگیرد. به طور کلی، مهمترین بخش این رم، رم خصوصی کثیف است که گرانترین بخش است زیرا فقط توسط فرآیند شما استفاده میشود و محتوای آن عمدتاً در رم فعال وجود دارد. در حالی که اندروید از فایلهای سنتی تعویض دیسک اجتناب میکند، از zRAM (فشردهسازی صفحه در حافظه) برای تعویض صفحات کثیف و گاهی اوقات از zRAM Writeback برای ذخیره صفحات بیکار در حافظه فلش استفاده میکند. با این حال، از آنجا که فشردهسازی صفحه هزینه دارد، چرخههای CPU و نوشتنهای فلش به شدت کنترل میشوند تا از فرسودگی سختافزار جلوگیری شود، رم خصوصی کثیف را نمیتوان بدون هزینه از سیستم خارج کرد. تمام تخصیصهای Dalvik و native heap که شما انجام میدهید، رم خصوصی کثیف هستند. تخصیصهای Dalvik و native که شما با فرآیند Zygote به اشتراک میگذارید، رم مشترک کثیف هستند.
- اندازه مجموعه متناسب (PSS)
- این معیاری برای سنجش میزان استفاده از رم توسط برنامه شماست که صفحات اشتراکی بین فرآیندها را در نظر میگیرد. هر صفحه رمی که مختص فرآیند شما باشد، مستقیماً در مقدار PSS آن نقش دارد، در حالی که صفحاتی که با سایر فرآیندها به اشتراک گذاشته میشوند، فقط به نسبت میزان اشتراکگذاری در مقدار PSS نقش دارند. به عنوان مثال، صفحهای که بین دو فرآیند به اشتراک گذاشته میشود، نیمی از اندازه خود را در PSS هر فرآیند به اشتراک میگذارد.
یکی از ویژگیهای اندازهگیری PSS این است که میتوانید PSS را در تمام فرآیندها جمع کنید تا میزان حافظه واقعی مورد استفاده توسط همه فرآیندها را تعیین کنید. این بدان معناست که PSS معیار خوبی برای وزن واقعی RAM یک فرآیند و برای مقایسه با میزان استفاده RAM توسط سایر فرآیندها و کل RAM موجود است.
برای مثال، خروجی زیر مربوط به فرآیند Map در دستگاه Nexus 5 است:
adb shell dumpsys meminfo -d com.google.android.apps.maps
توجه: اطلاعاتی که میبینید ممکن است کمی با آنچه در اینجا نشان داده شده است متفاوت باشد، زیرا برخی از جزئیات خروجی در نسخههای مختلف پلتفرم متفاوت است.
** 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
در اینجا یک dumpsys قدیمیتر در Dalvik از برنامه Gmail آمده است:
** 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دارند،Pss TotalوPrivate Dirtynumbers برای Dalvik Heap شامل سربار Dalvik، مانند کامپایل درجا (JIT) و حسابداری GC، نمیشوند، در حالی که نسخههای قدیمیتر همه این موارد را به صورت ترکیبی تحت عنوانDalvikفهرست میکنند.Heap Allocمقدار حافظهای است که تخصیصدهندههای Dalvik و native heap برای برنامه شما پیگیری میکنند. این مقدار ازPss TotalوPrivate Dirtyبزرگتر است زیرا فرآیند شما از Zygote منشعب شده است و شامل تخصیصهایی است که فرآیند شما با سایر فرآیندها به اشتراک میگذارد. -
.so mmapو.dex mmap - رمی که برای کد
.so(بومی) و.dex(دالویک یا ART) نگاشت شده استفاده میشود. عددPss Totalشامل کد پلتفرم مشترک بین برنامهها است.Private Cleanکد خود برنامه شماست. به طور کلی، اندازه واقعی نگاشت شده بزرگتر است. رم در اینجا فقط چیزی است که در حال حاضر برای کدی که توسط برنامه اجرا شده است، باید در رم باشد. با این حال،.so mmapدارای private dirty بزرگی است که به دلیل اصلاحات کد بومی هنگام بارگذاری در آدرس نهایی آن است. -
.oat mmap - این مقدار رمی است که توسط تصویر کد استفاده میشود. این مقدار بر اساس کلاسهای از پیش بارگذاری شدهای است که معمولاً توسط چندین برنامه استفاده میشوند. این تصویر در همه برنامهها به اشتراک گذاشته میشود و تحت تأثیر برنامههای خاص قرار نمیگیرد.
-
.art mmap - این مقدار رم مورد استفاده توسط تصویر پشته است. این مقدار بر اساس کلاسهای از پیش بارگذاری شدهای است که معمولاً توسط چندین برنامه استفاده میشوند. این تصویر در همه برنامهها به اشتراک گذاشته میشود و تحت تأثیر برنامههای خاص قرار نمیگیرد. حتی اگر تصویر ART حاوی نمونههای
Objectباشد، در اندازه پشته شما محاسبه نمیشود. -
.Heap(فقط با پرچم-d) - این مقدار حافظه heap برای برنامه شماست. این مقدار شامل اشیاء موجود در تصویر و فضاهای بزرگ اشیاء نمیشود، اما فضای Zygote و فضای غیرمتحرک را شامل میشود.
-
.LOS(فقط با پرچم-d) - این مقدار رم مورد استفاده توسط فضای اشیاء بزرگ ART است. این شامل اشیاء بزرگ Zygote نیز میشود. اشیاء بزرگ، همگی تخصیصهای آرایه اولیه بزرگتر از ۱۲ کیلوبایت هستند.
-
.GC(فقط با پرچم-d) - این هزینه سربار برای جمعآوری زباله است. هیچ راهی برای کاهش این سربار وجود ندارد.
-
.JITCache(فقط با پرچم-d) - این مقدار حافظهای است که توسط دادههای JIT و حافظههای پنهان کد استفاده میشود. معمولاً این مقدار صفر است، زیرا همه برنامهها در زمان نصب کامپایل میشوند.
-
.Zygote(فقط با پرچم-d) - این مقدار حافظهای است که توسط فضای Zygote استفاده میشود. فضای Zygote هنگام راهاندازی دستگاه ایجاد میشود و هرگز تخصیص داده نمیشود.
-
.NonMoving(فقط با پرچم-d) - این مقدار رمی است که توسط فضای غیرمتحرک ART استفاده میشود. فضای غیرمتحرک شامل اشیاء غیرمتحرک خاص مانند فیلدها و متدها است. میتوانید با استفاده از فیلدها و متدهای کمتر در برنامه خود، این بخش را کاهش دهید.
-
.IndirectRef(فقط با پرچم-d) - این مقدار رمی است که توسط جداول ارجاع غیرمستقیم ART استفاده میشود. معمولاً این مقدار کم است، اما اگر خیلی زیاد باشد، میتوانید با کاهش تعداد ارجاعات JNI محلی و سراسری مورد استفاده، آن را کاهش دهید.
-
Unknown - هر صفحه رمی که سیستم نتوانسته آن را در یکی از موارد خاصتر طبقهبندی کند. در حال حاضر، این شامل تخصیصهای عمدتاً بومی است که به دلیل تصادفیسازی طرحبندی فضای آدرس (ASLR) توسط ابزار هنگام جمعآوری این دادهها قابل شناسایی نیستند. مانند هیپ دالویک،
Pss TotalبرایUnknown، اشتراکگذاری با Zygote را در نظر میگیرد وPrivate Dirtyرم ناشناختهای است که فقط به برنامه شما اختصاص داده شده است. -
TOTAL - کل حافظه رم (PSS) که توسط فرآیند شما استفاده میشود. این مجموع تمام فیلدهای PSS بالای آن است. این نشان دهنده وزن کلی حافظه فرآیند شماست که میتواند مستقیماً با سایر فرآیندها و کل حافظه رم موجود مقایسه شود.
Private DirtyوPrivate Cleanکل تخصیصهای درون فرآیند شما هستند که با سایر فرآیندها به اشتراک گذاشته نمیشوند. هنگامی که فرآیند شما از بین میرود، تمام RAM حاصل از این تخصیصها به سیستم بازگردانده میشود.Private Cleanهمچنین میتواند قبل از از بین رفتن فرآیند شما، صفحهبندی و آزاد شود، اماPrivate Dirtyفقط در زمان تخریب فرآیند آزاد میشود.رم کثیف صفحاتی هستند که تغییر یافتهاند و یا در رم فعال نگهداری میشوند، در zRAM فشرده میشوند یا دوباره به حافظه نوشته میشوند. رم تمیز صفحاتی هستند که از یک فایل پایدار، مانند کدی که در حال اجرا است، نگاشت شدهاند و در صورت عدم استفاده برای مدتی، میتوانند از حافظه خارج شوند.
-
ViewRootImpl - تعداد نماهای ریشهای که در فرآیند شما فعال هستند. هر نمای ریشه با یک پنجره مرتبط است، بنابراین این میتواند به شما در شناسایی نشت حافظه مربوط به دیالوگها یا سایر پنجرهها کمک کند.
-
AppContextsوActivitiesبرنامه - تعداد اشیاء
ContextوActivityبرنامه که در حال حاضر در فرآیند شما وجود دارند. این میتواند به شما کمک کند تا اشیاءActivityنشت یافتهای را که به دلیل ارجاعات استاتیک روی آنها، که رایج است، نمیتوان آنها را garbage collector کرد، به سرعت شناسایی کنید. این اشیاء اغلب تخصیصهای دیگری نیز با خود دارند که آنها را به راهی خوب برای ردیابی نشتهای حافظه بزرگ تبدیل میکند.