דאמפסי

dumpsys הוא כלי שפועל במכשירי Android ומספק מידע על שירותי המערכת שלנו. קוראים לפונקציה dumpsys משורת הפקודה באמצעות הפקודה גשר לניפוי באגים ב-Android (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. רשימת האפשרויות הזמינות עבור דאמפסי

אפשרות תיאור
-t timeout לציין את פרק הזמן הקצוב לתפוגה בשניות. אם לא צוין אחרת, הפונקציה ערך ברירת המחדל הוא 10 שניות.
--help אפשר להדפיס טקסט עזרה לכלי dumpsys.
-l יוצרים פלט של רשימה מלאה של שירותי המערכת שבהם אפשר להשתמש עם dumpsys
--skip services מציינים את קטגוריית services שלא רוצים לכלול. הפלט.
service [arguments] מציינים את הservice שרוצים לקבל כפלט. שירותים מסוימים עשויות לאפשר לך להעביר את arguments האופציונלי. כדי ללמוד על את הארגומנטים האופציונליים האלה, מעבירים את האפשרות -h עם service:
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 אחראי לפענוח אירועי קלט מהליבה. שלו מצב Dump מציג מידע על האופן שבו מוגדר כל מכשיר קלט שינויים שנעשו לאחרונה במצב, כגון לחיצות על מקשים או נגיעות מסך מגע.

הדוגמה הבאה מציגה את הפלט של מסך מגע. מעיינים במידע על הרזולוציה של המכשיר ופרמטרים של כיול בשימוש.

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 לשילוב ממשק המשתמש למדוד ביצועים במסגרת שיטות הבדיקה, כתיבה של נקודת מאקרו בנצ'מרק.

בדיקת אבחון הרשת

ציון השירות netstats מספק נתוני שימוש ברשת שנאספו מאז שהמכשיר הקודם אותחל. כדי להפיק מידע נוסף, כמו מידע מפורט על מזהה משתמש ייחודי (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]

בעזרת קובץ ה-Dump לדוגמה הקודם, מחפשים שורות עם uid=10007. שניים כאלה קיימים - הראשון מציין חיבור סלולרי והשני מציין חיבור Wi-Fi. מתחת לכל שורה מופיע המידע הבא לגבי כל חלון של שעתיים, שמציין bucketDuration באלפיות שנייה:

  • set=DEFAULT מציין את החזית השימוש ברשת, בעוד שהמאפיין set=BACKGROUND מציין שימוש ברקע. set=ALL משתמע משניהם.
  • tag=0x0 מציין את תג ה-socket שמשויך לתנועה.
  • rxBytes ו-rxPackets מייצגים בייטים שהתקבלו והחבילות שהתקבלו בפרק הזמן המתאים.
  • txBytes ו-txPackets מייצגות את ההודעות שנשלחו בייטים (שודרו) והחבילות שנשלחו בפרק הזמן המתאים.

בדיקת אבחון הסוללה

ציון השירות batterystats יוצר נתונים סטטיסטיים מידע על השימוש בסוללה במכשיר, בחלוקה לפי מזהה משתמש ייחודי (UID). כדי ללמוד איך כדי להשתמש ב-dumpsys כדי לבדוק את האפליקציה עבור Doze ו-App Standby, ניתן לעיין בדיקה באמצעות 'נמנום' ו'מצב המתנה'.

הפקודה עבור batterystats היא:

adb shell dumpsys batterystats options

כדי לראות רשימה של אפשרויות נוספות שזמינות ל-batterystats, צריך לכלול את אפשרות -h. הדוגמה הבאה מציגה נתונים סטטיסטיים של שימוש בסוללה חבילת האפליקציה שצוינה מאז שהמכשיר חויב לאחרונה:

adb shell dumpsys batterystats --charged package-name

הפלט בדרך כלל כולל את הדברים הבאים:

  • היסטוריה של אירועים שקשורים לסוללה
  • נתונים סטטיסטיים גלובליים עבור המכשיר
  • צריכת חשמל משוערת לכל UID ורכיב מערכת
  • אלפיות שנייה לנייד לפי אפליקציה לכל מנה
  • נתונים סטטיסטיים מצטברים על UID של המערכת
  • נתונים סטטיסטיים מצטברים לגבי UID של האפליקציה

למידע נוסף על השימוש ב-batterystats ועל יצירת המחשה חזותית של HTML הפלט, וכך קל יותר להבין ולאבחן בעיות שקשורות לסוללה כדי לפתור בעיות, אפשר לקרוא את המאמר שימוש בסוללת פרופיל עם התכונה 'סוללה' ו'היסטוריית הסוללה'.

בדיקת פלט ידידותי למחשבים

אפשר ליצור פלט 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 או ברמת המערכת. נבחרו נתונים עבור לפי השימושיות שלו בניתוח ביצועי הסוללה. כל שורה שמייצג תצפית, כולל את הרכיבים הבאים:

  • מספר שלם מסוג placeholder
  • מזהה המשתמש שמשויך לתצפית
  • מצב הצבירה:
    • i למידע שלא קשור לסטטוס 'חויב'/'לא חויב'.
    • l ל---charged (השימוש מאז הטעינה האחרונה).
    • u ל---unplugged (השימוש מאז הניתוק האחרון). הוצא משימוש ב- Android 5.1.1.
  • מזהה הקטע, קובע איך לפרש את הערכים הבאים בשורה.

בטבלה הבאה מתוארים מזהי הקטעים השונים שאתם עשויים לראות:

טבלה 2. רשימה של מזהי קטעים

מזהה החלק תיאור השדות שנותרו

vers

גרסה

checkin version, parcel version, start platform version, end platform version

uid

UID

uid, package name

apk

APK

wakeups, APK, service start time, starts, launches

pr

תהליך

process, user, system foreground, starts

sr

חיישן

sensor number, time count

vib

רטט

time, count

fg

חזית

time, count

st

זמן מדינה

foreground, active running

wl

נעילה ליציאה ממצב שינה

wake lock, full time, f full count, partial time, p, partial count, window time, w, window count

sy

סנכרון

sync, time count

jb

משרה

job, time count

kwl

נעילת ליבה (kernel)

kernel wake lock, time count

wr

סיבת ההתעוררות

wakeup reason, time count

nt

רשת

mobile bytes RX, mobile bytes TX Wi-Fi bytes RX, Wi-Fi bytes TX mobile packets RX, mobile packets TX, Wi-Fi packets RX, Wi-Fi packets TX, mobile active time, mobile active count

ua

פעילות משתמש

other, button touch

bt

סוללה

start count, battery realtime battery uptime, total realtime total uptime, start clock time, battery screen off realtime, battery screen off uptime

dc

פריקת סוללה

low, high, screen on screen off

lv

רמת סוללה

start level, current level

wfl

Wi-Fi

full Wi-Fi lock on time, Wi-Fi scan time, Wi-Fi running time Wi-Fi scan count, Wi-Fi idle time, Wi-Fi receive time, Wi-Fi transmit time

gwfl

Wi-Fi גלובלי

Wi-Fi on time, Wi-Fi running time Wi-Fi idle time, Wi-Fi receive time, Wi-Fi transmit time, Wi-Fi power (mAh)

gble

Bluetooth גלובלי

BT idle time, BT receive time BT transmit time, BT power (mAh)

m

שונות

screen on time, phone on time full wakelock time total, partial wakelock time total, mobile radio active time, mobile radio active adjusted time, interactive time, power save mode enabled time, connectivity changes, device idle mode enabled time, device idle mode enabled count, device idling time, device idling count, mobile radio active count, mobile radio active unknown time

gn

רשת גלובלית

mobile RX total bytes, mobile TX total bytes Wi-Fi RX total bytes, Wi-Fi TX total bytes mobile RX total packets, mobile TX total packets, Wi-Fi RX total packets, Wi-Fi TX total packets

br

בהירות המסך

dark, dim, medium light, bright

sst

זמן סריקת אותות

signal scanning time

sgt

זמן עוצמת האות

none, poor, moderate good, great

sgc

מספר עוצמת האות

none, poor, moderate good, great

dct

זמן חיבור הנתונים

none, GPRS, EDGE UMTS, CDMA, EVDO_0, EVDO_A, 1xRTT, HSDPA, HSUPA, HSPA, IDEN, EVDO_B, LTE, EHRPD, HSPAP, other

dcc

מספר חיבורי הנתונים

none, GPRS, EDGE, UMTS CDMA, EVDO_0, EVDO_A, 1xRTT, HSDPA, HSUPA, HSPA, IDEN, EVDO_B, LTE, EHRPD, HSPAP, other

wst

שעון מצב ה-Wi-Fi

off, off scanning, on no networks on disconnected, on connected STA, on connected P2P, on connected STA P2P, soft AP

wsc

מספר מצבי ה-Wi-Fi

off, off scanning, on no networks on disconnected, on connected STA, on connected P2P, on connected STA P2P, soft AP

wsst/p>

מצב האספקה של ה-Wi-Fi

invalid, disconnected interface disabled, inactive, scanning, authenticating, associating, associated, four-way handshake, group handshake, completed, dormant, uninitialized

wssc

מספר המצבים של ספקי Wi-Fi

invalid, disconnected, interface disabled, inactive, scanning, authenticating, associating, associated, four-way handshake, group handshake, completed, dormant, uninitialized

wsgt

משך הזמן של אות ה-Wi-Fi

none, poor, moderate good, great

wsgc

מספר עוצמת האות של ה-Wi-Fi

none, poor, moderate good, great

bst

זמן מצב Bluetooth

inactive, low, med high

bsc

מספר מצבי Bluetooth

inactive, low, med high

pws

סיכום השימוש בסוללה

battery capacity, computed power minimum drained power, maximum drained power

pwi

פריט לשימוש חזק

label, mAh

dsd

שלב הפריקה

duration, level, screen power-save

csd

שלב חיוב

duration, level, screen power-save

dtr

הזמן שנותר לפליטת הנתונים

battery time remaining

ctr

הזמן שנשאר לטעינה

charge time remaining

הערה: לפני Android 6.0, צריכת החשמל הייתה בשביל בוצע מעקב אחר רדיו, רדיו סלולרי ו-Wi-Fi ב-m (שונות) בקטגוריה הזו. ב-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

ממים

אפשר לצלם תמונת מצב של הזיכרון של האפליקציה מחולקים בין סוגים שונים של הקצאת RAM עם הפקודה הבאה:

adb shell dumpsys meminfo package_name|pid [-d]

הדגל -d מדפיס מידע נוסף שקשור לשימוש בזיכרון של Dalvik ו-ART.

הפלט מפרט את כל ההקצאות הנוכחיות של האפליקציה, שנמדדות קילובייט (KB).

כשתבדקו את המידע הזה, חשוב שתכירו את סוגי ההקצאה הבאים:

זיכרון RAM פרטי (נקי ומלוכלך)
זהו זיכרון שנמצא בשימוש רק בתהליך שלך. אלה הכמות הגדולה של זיכרון ה-RAM שהמערכת יכולה לשחזר כשהתהליך של האפליקציה מושמד. באופן כללי, החלק החשוב ביותר בזה הוא זיכרון RAM פרטי, היא היקרה ביותר, כי היא משמשת רק את התהליך שלך ובגלל שהיא תכנים קיימים רק ב-RAM, ולכן לא ניתן להעביר אותם לדפים לאחסון, כי מערכת Android לא להשתמש בהחלפה. כל הקצאות הערימה (heap) המקוריות שעושים Dalvik וכאלה שמבוצעות הן מלוכלכות פרטי וגם זיכרון RAM. ההקצאות המקוריות וההקצאות המקוריות שאתה משתף עם תהליך Zygote משותפות ו-RAM מלוכלך.
גודל קבוצה יחסי (PSS)
זו מדידה של השימוש ב-RAM של האפליקציה שמביאה בחשבון שיתוף דפים שונים בתהליכים שונים. דפי RAM שהם ייחודיים לתהליך שלכם באופן ישיר תורמים לערך ה-PSS שלו, ואילו דפים ששותפו עם תהליכים אחרים לתרום לערך ה-PSS רק ביחס לכמות השיתוף. עבור לדוגמה, דף שמשותף בין שני תהליכים תורם מחצית מהגודל שלו PSS של כל תהליך.

מאפיין של מדידת PSS הוא שאפשר לחבר את ה-PSS בכל את כל התהליכים כדי לקבוע איזה זיכרון נמצא בשימוש בפועל בכל התהליכים. הזה כלומר PSS הוא מדד טוב למשקל ה-RAM בפועל של תהליך, השוואה בין השימוש ב-RAM לשימוש בתהליכים אחרים לבין השימוש הכולל בתהליכים אחרים וגם זיכרון RAM.

לדוגמה, הדוגמה הבאה היא הפלט של תהליך המפה ב-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

הנה גרסה ישנה יותר של 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
נפח ה-RAM שמשמש להקצאות של Dalvik באפליקציה. Pss Total כולל את כל ההקצאות של Zygote, המשוקללות על ידי השיתוף שלהן בין תהליכים, וכן שמתוארים בהגדרת ה-PSS. המספר של Private Dirty הוא את נפח ה-RAM בפועל שמחויב רק לערימת האפליקציה, שמורכבת מההקצאות שלך וכל דפי הקצאת Zygote שהשתנו מאז ש מ-Zygote.

הערה: בגרסאות חדשות יותר של הפלטפורמה שכוללות את הקטע הקטע Dalvik Other, מספרי Pss Total ו-Private Dirty של Dalvik Heap לא כוללים תקורה של Dalvik, כמו איסוף בזמן אמת (JIT) וניהול חשבונות GC, לעומת גרסאות ישנות יותר הכול משולב במסגרת Dalvik.

Heap Alloc הוא כמות הזיכרון שה-Dalvik הקצאת ערימה מקורית עוקבת אחר האפליקציה שלך. הערך הזה גדול מ- Pss Total ו-Private Dirty, כי התהליך שלך היה שפוצל מ-Zygote, כולל הקצאות שהתהליך משתף עם כל אחרים.

.so mmap וגם .dex mmap
ה-RAM שמשמש למיפוי של .so (מקורי) וגם קוד .dex (Dalvik או ART). המספר של Pss Total כולל קוד פלטפורמה שמשותף בין אפליקציות. Private Clean הוא את הקוד של האפליקציה עצמה. בדרך כלל, הגודל הממופה בפועל גדול יותר. זיכרון ה-RAM כאן הוא רק מה שצריך כרגע ב-RAM עבור קוד שהופעל על ידי אפליקציה. עם זאת, יש ב.so mmap לכלוך פרטי גדול בגלל תיקונים לקוד המקורי כשהוא נטען בכתובת הסופית.
.oat mmap
זה נפח ה-RAM שמשמש את תמונת הקוד. מבוסס על כיתות שנטענו מראש שנמצאות בשימוש על ידי אפליקציות מרובות. התמונה הזו משותפת בכל האפליקציות, והוא לא מושפע מאפליקציות מסוימות.
.art mmap
זה נפח ה-RAM שמשמש את תמונת הערימה. מבוסס על כיתות שנטענו מראש שנמצאות בשימוש על ידי אפליקציות מרובות. התמונה הזו משותפת בין כל האפליקציות, והוא לא מושפע מאפליקציות מסוימות. למרות שתמונת ART מכיל Object הוא לא נחשב בגודל הערימה.
.Heap (רק עם הדגל -d)
זה נפח זיכרון הזיכרון של האפליקציה. זה לא כולל אובייקטים בתמונה ובאובייקטים גדולים, אבל הוא כולל את מרחב זיגוטה המרחב המשותף.
.LOS (רק עם הדגל -d)
זה נפח ה-RAM שמשמש את מרחב האובייקטים הגדול של ART. המידע הזה כולל זיגוטים גדולים. אובייקטים גדולים הם כל הקצאות המערכים פרימיטיביות גדולות יותר יותר מ-12KB.
.GC (רק עם הדגל -d)
זו העלות התקורה של איסוף אשפה. אין כדי לצמצם את התקורה הזו.
.JITCache (רק עם הדגל -d)
זה נפח הזיכרון שמשמש את נתוני ה-JIT ואת מטמוני הקוד. בדרך כלל, המספר הוא אפס כי כל האפליקציות עוברות הידור בזמן ההתקנה בזמן האימון.
.Zygote (רק עם הדגל -d)
זה נפח הזיכרון שמרחב Zygote משתמש בו. חלל Zygote הוא נוצר במהלך ההפעלה של המכשיר ואף פעם לא מוקצה לו.
.NonMoving (רק עם הדגל -d)
זה נפח ה-RAM שמשמש את האחסון ב-ART שלא נע. מודעות שלא זזות מכיל אובייקטים מיוחדים שלא ניתנים להעברה, כמו שדות ושיטות. אפשר מצמצמים את הקטע הזה על ידי שימוש בפחות שדות ושיטות באפליקציה.
.IndirectRef (רק עם הדגל -d)
זה נפח ה-RAM שמשמש את טבלאות העזר העקיפות של ART. בדרך כלל הסכום הזה נמוך, אך אם הוא גבוה מדי, ייתכן שתוכל לצמצם אותו על ידי צמצום מספר ההפניות המקומיות והגלובליות שבהן נעשה שימוש ב-JNI.
Unknown
דפי RAM שהמערכת לא הצליחה לסווג לאחד הדפים האחרים פריטים ספציפיים. נכון לעכשיו, הפיד מכיל בעיקר הקצאות מקוריות, שלא ניתן יזוהו על ידי הכלי במהלך איסוף הנתונים האלו באמצעות הפריסה של מרחב הכתובות ארגון בסדר אקראי (ASLR). כמו ערימת Dalvik, גם Pss Total בשביל Unknown מביא בחשבון שיתוף עם Zygote ועם Private Dirty הוא זיכרון RAM לא ידוע שמיועד רק לאפליקציה שלך.
TOTAL
ה-RAM הכולל של גודל ההגדרה היחסי (PSS) שנעשה בו שימוש בתהליך. כאן סכום כל שדות ה-PSS שמעליו. הוא מציין את המשקל הכולל של הזיכרון לעיבוד נתונים, שאפשר להשוות אותו ישירות לתהליכים אחרים, ונפח ה-RAM הזמין.

Private Dirty ו-Private Clean הם המספר הכולל הקצאות בתהליך, שלא משותפות עם תהליכים אחרים. כשהתהליך מושמד, כל נפח ה-RAM מההקצאות האלה משוחרר חזרה למערכת. אפשר גם להעביר לדפים את Private Clean ולשחרר אותם לפני שהתהליך שלך ייהרס, אבל Private Dirty הוא רק הושק לאחר השמדת תהליך.

ה-RAM המלוכלך הוא דפים שבוצעו בהם שינויים ולכן חייבים להישאר מחויבים ל-RAM מפני שיש ללא החלפה. זיכרון RAM נקי הוא דפים שמופו מקובץ קבוע, כקוד בהרצה, וניתן לשלוח אותו לדף אם לא משתמשים בו במשך זמן מה.

ViewRootImpl
מספר הצפיות ברמה הבסיסית (root) שפעילות בתהליך שלך. כל תצוגה מפורטת ברמה הבסיסית היא שמשויכים לחלון, כך שתוכלו לזהות דליפות זיכרון שכוללות תיבות דו-שיח או חלונות אחרים.
AppContexts וגם Activities
מספר האפליקציה Context ו-Activity שקיימים כרגע בתהליך שלכם. זה יכול לעזור לכם זיהוי אובייקטים שדלפו Activity שאי אפשר לאסוף אשפה עקב הפניות סטטיות אליהם, זה תופעה נפוצה. לאובייקטים האלה יש הרבה הקצאות אחרות שמשויכות אליהם, כך שהם יכולים להיות דרך טובה לעקוב דליפות זיכרון גדולות.