dumpsys

dumpsys는 Android 기기에서 실행하는 시스템 서비스 정보 제공 도구입니다. dumpsysAndroid 디버그 브리지(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를 사용할 때 이용할 수 있는 옵션의 목록입니다.

옵션 설명
-t timeout 시간 제한 기간을 초 단위로 지정합니다. 지정되지 않으면 기본값은 10초입니다.
--help dumpsys 도구의 도움말 텍스트를 출력합니다.
-l dumpsys 와 함께 사용할 수 있는 시스템 서비스의 전체 목록을 출력합니다.
--skip services 출력에서 제외하려는 서비스를 지정합니다.
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는 커널의 입력 이벤트를 디코딩합니다. 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 필드의 비트는 INPUT_DEVICE_CLASS_TOUCH_MT와 같은 EventHub.h의 플래그에 해당합니다.
  • BuiltInKeyboardId가 정확합니다. 기기에 내장 키보드가 없다면 ID는 -2여야 합니다. 또는 내장 키보드의 ID여야 합니다.
    • BuiltInKeyboardId-2여야 하는데 그렇지 않다면 특수 기능 키패드의 키 문자 맵 파일이 누락된 것입니다. 특수 기능 키패드 기기에는 type SPECIAL_FUNCTION 행만 포함하는 키 문자 맵 파일이 있어야 합니다(위에서 언급된 tuna-gpio-keykad.kcm 파일 내부에 있음).

입력 리더 상태:

  • 일반적인 모든 입력 기기가 포함되어 있습니다.
  • 각 입력 기기가 정확히 구성되어 있습니다. 특히 터치스크린 및 조이스틱 축이 정확히 구성되어 있는지 확인하세요.

입력 디스패처 상태:

  • 모든 입력 이벤트가 일반적인 방식으로 처리됩니다.
  • 터치스크린을 터치하는 동시에 dumpsys를 실행한 후 TouchStates 행이 터치하고 있는 창을 올바르게 식별합니다.

UI 성능 테스트

gfxinfo 서비스를 지정하면 기록 단계 중에 발생하는 애니메이션 프레임 관련 성능 정보가 담긴 출력이 제공됩니다. 다음 명령어는 gfxinfo를 사용하여 지정된 패키지 이름의 UI 성능 데이터를 수집합니다.

    adb shell dumpsys gfxinfo package-name
    

또한 다음과 같이 framestats 옵션을 포함하여 최근 프레임의 자세한 프레임 타이밍 정보를 제공할 수 있으므로 더 정확하게 문제를 추적하고 디버깅할 수 있습니다.

    adb shell dumpsys gfxinfo package-name framestats
    

gfxinfoframestats를 사용하여 테스트에 UI 성능 측정값을 통합하는 방법을 자세히 알아보려면 UI 성능 테스트로 이동하세요.

네트워크 진단 검사

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"}]
    

'Dev' 및 'Xt' 통계

다음은 Dev 통계 섹션의 샘플 출력입니다.

    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은 트래픽과 연결된 소켓 태그를 나타냅니다.
  • rxBytesrxPackets는 해당하는 시간 간격에 수신한 바이트와 패킷을 나타냅니다.
  • txBytestxPackets는 해당하는 시간 간격에 전송한 바이트와 패킷을 나타냅니다.

배터리 진단 검사

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으로 배터리 사용량 프로파일링을 참조하세요. HTML 시각화를 생성하면 배터리 관련 문제를 더 쉽게 파악하고 진단할 수 있습니다.

기기에서 처리하기 쉬운 출력 검사

다음 명령어를 사용하여 기기가 읽을 수 있는 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 또는 시스템 수준별로 표시될 수 있습니다. 데이터는 배터리 성능 분석에 유용한 정도에 따라 선택되어 포함됩니다. 각 행은 다음 요소가 있는 관찰값을 나타냅니다.

  • 더미 정수
  • 관찰과 연결된 사용자 ID
  • 집계 모드:
    • 'i': 충전/미충전 상태와 관련 없는 정보
    • 'l': 충전됨(마지막으로 충전한 이후 사용량)
    • 'u': 연결 해제됨(마지막으로 연결 해제한 이후 사용량). Android 5.1.1에서 지원 중단됨
  • 행의 후속값 해석 방법을 결정하는 섹션 식별자

아래 표는 표시될 수 있는 다양한 섹션 식별자를 설명합니다.

섹션 식별자 설명 남은 필드

vers

버전

체크인 버전, 파일 집합 버전, 시작 플랫폼 버전, 종료 플랫폼 버전

uid

UID

UID, 패키지 이름

apk

APK

wakeup, APK, 서비스, 시작 시간, 시작, 실행

pr

처리

프로세스, 사용자, 시스템, 포그라운드, 시작

sr

센서

센서 번호, 시간, 횟수

vib

바이브레이터

시간, 횟수

fg

포그라운드

시간, 횟수

st

상태 시간

포그라운드, 활성, 실행 중

wl

wake lock

wake lock, 전체 시간, 'f', 전체 횟수, 부분 시간, 'p', 부분 횟수, 창 시간, 'w', 창 개수

sy

동기화

동기화, 시간, 횟수

jb

작업

작업, 시간, 횟수

kwl

커널 wake lock

커널 wake lock, 시간, 횟수

wr

wakeup 이유

wakeup reason, 시간, 횟수

nt

네트워크

모바일 바이트 RX, 모바일 바이트 TX, Wi-Fi 바이트 RX, Wi-Fi 바이트 TX, 모바일 패킷 RX, 모바일 패킷 TX, Wi-Fi 패킷 RX, Wi-Fi 패킷 TX, 모바일 활성 시간, 모바일 활성 횟수

ua

사용자 활동

기타, 버튼, 터치

bt

배터리

시작 횟수, 배터리 실시간, 배터리 가동시간, 총 실시간, 총 가동시간, 시작 시계 시간, 배터리 화면 꺼짐 실시간, 배터리 화면 꺼짐 가동시간

dc

배터리 사용량

낮음, 높음, 화면 켜짐, 화면 꺼짐

lv

배터리 수준

시작 수준, 현재 수준

wfl

Wi-Fi

전체 Wi-Fi 잠금 시간, Wi-Fi 스캔 시간, Wi-Fi 실행 시간, Wi-Fi 스캔 횟수, Wi-Fi 유휴 시간, Wi-Fi 수신 시간, Wi-Fi 전송 시간

gwfl

전역 Wi-Fi

Wi-Fi 가동 시간, Wi-Fi 실행 시간, Wi-Fi 유휴 시간, Wi-Fi 수신 시간, Wi-Fi 전송 시간, Wi-Fi 전원(mAh)

gble

전역 블루투스

BT 유휴 시간, BT 수신 시간, BT 전송 시간, BT 전원(mAh)

m

기타

화면 가동 시간, 휴대전화 가동 시간, 총 전체 wakelock 시간, 총 부분 wakelock 시간, 무선 통신 활성 시간, 무선 통신 활성 조정 시간, 상호작용 시간, 절전 모드 사용 시간, 연결 변경, 기기 유휴 모드 사용 시간, 기기 유휴 모드 사용 횟수, 기기 유휴 시간, 기기 유휴 횟수, 무선 통신 활성 횟수, 무선 통신 활성 알 수 없는 시간

gn

전역 네트워크

모바일 RX 총 바이트, 모바일 TX 총 바이트, Wi-Fi RX 총 바이트, Wi-Fi TX 총 바이트, 모바일 RX 총 패킷, 모바일 TX 총 패킷, Wi-Fi RX 총 패킷, Wi-Fi TX 총 패킷

br

화면 밝기

어둡게, 조금 어둡게, 중간, 조금 밝게, 밝게

sst

신호 스캐닝 시간

신호 스캐닝 시간

sgt

신호 강도 시간

없음, 약함, 보통, 양호, 좋음

sgc

신호 강도 횟수

없음, 약함, 보통, 양호, 좋음

dct

데이터 연결 시간

없음, GPRS, EDGE, UMTS, CDMA, EVDO_0, EVDO_A, 1xRTT, HSDPA, HSUPA, HSPA, IDEN, EVDO_B, LTE, EHRPD, HSPAP, 기타

dcc

데이터 연결 횟수

없음, GPRS, EDGE, UMTS, CDMA, EVDO_0, EVDO_A, 1xRTT, HSDPA, HSUPA, HSPA, IDEN, EVDO_B, LTE, EHRPD, HSPAP, 기타

wst

Wi-Fi 상태 시간

꺼짐, 스캔 꺼짐, 네트워크 없음, 연결 해제, STA 연결, P2P 연결, STA P2P 연결, 소프트 AP

wsc

Wi-Fi 상태 횟수

꺼짐, 스캔 꺼짐, 네트워크 없음, 연결 해제, STA 연결, P2P 연결, STA P2P 연결, 소프트 AP

wsst

Wi-Fi 서플리컨트 상태 시간

유효하지 않음, 연결 해제됨, 인터페이스 사용 안함, 비활성, 스캔 중, 인증 중, 연결 중, 연결됨, 4방향 핸드셰이크, 그룹 핸드셰이크, 완료됨, 휴면, 초기화되지 않음

wssc

Wi-Fi 서플리컨트 상태 횟수

유효하지 않음, 연결 해제됨, 인터페이스 사용 안함, 비활성, 스캔 중, 인증 중, 연결 중, 연결됨, 4방향 핸드셰이크, 그룹 핸드셰이크, 완료됨, 휴면, 초기화되지 않음

wsgt

Wi-Fi 신호 강도 시간

없음, 약함, 보통, 양호, 좋음

wsgc

Wi-Fi 신호 강도 횟수

없음, 약함, 보통, 양호, 좋음

bst

블루투스 상태 시간

비활성, 낮음, 중간, 높음

bsc

블루투스 상태 횟수

비활성, 낮음, 중간, 높음

pws

전원 사용 요약

배터리 용량, 계산된 전력 사용량, 최소 방전 전력, 최대 방전 전력

pwi

전원 사용 항목

라벨, mAh

dsd

사용 단계

기간, 수준, 화면, 절전

csd

충전 단계

기간, 수준, 화면, 절전

dtr

남은 사용 시간

남은 배터리 시간

ctr

남은 충전 시간

남은 충전 시간

참고: Android 6.0 미만 버전에서는 블루투스 라디오, 무선 라디오, Wi-Fi의 전원 사용이 m(기타) 섹션 카테고리에서 추적되었습니다. Android 6.0 이상 버전에서는 이러한 구성요소의 전원 사용이 pwi(전원 사용 항목) 섹션에서 추적되며, 각 구성요소에 해당하는 개별 라벨(wifi, blue, cell)이 있습니다.

메모리 할당 보기

procstats를 사용하여 일정 기간 동안의 앱 메모리 사용량을 검사하거나 meminfo를 사용하여 특정 시간의 사용량을 검사할 수 있습니다. 아래 섹션에서는 두 가지 방식을 사용하는 방법을 설명합니다.

procstats

procstats를 통해 백그라운드 실행 시간이나 해당 시간 동안의 메모리 소모량 등 일정 기간의 앱 동작을 확인할 수 있습니다. 이렇게 하면 특히 앱이 메모리가 부족한 기기에서 실행될 때 메모리 누수와 같이 앱의 성능에 영향을 미칠 수 있는 비효율성이나 문제를 빠르게 찾을 수 있습니다. 상태 덤프는 모든 애플리케이션의 런타임, PSS(Proportional Set Size), USS(Unique Set Size)에 관한 통계를 표시합니다.

사람이 읽을 수 있는 형식으로 지난 3시간 동안의 애플리케이션 메모리 사용 통계를 받아 보려면 다음 명령어를 실행하세요.

adb shell dumpsys procstats --hours 3

아래 예에서 확인할 수 있는 것처럼 출력에는 애플리케이션이 실행된 시간의 비율과 PSS 및 USS가 샘플 수에 대한 minPSS-avgPSS-maxPSS/minUSS-avgUSS-maxUSS로 표시됩니다.

    AGGREGATED OVER LAST 3 HOURS:
      * com.android.systemui / u0a20 / v22:
               TOTAL: 100% (109MB-126MB-159MB/108MB-125MB-157MB over 18)
          Persistent: 100% (109MB-126MB-159MB/108MB-125MB-157MB over 18)
      * com.android.nfc / 1027 / v22:
               TOTAL: 100% (17MB-17MB-17MB/16MB-16MB-16MB over 18)
          Persistent: 100% (17MB-17MB-17MB/16MB-16MB-16MB over 18)
      * android.process.acore / u0a4 / v22:
               TOTAL: 100% (14MB-15MB-15MB/14MB-14MB-14MB over 20)
              Imp Fg: 100% (14MB-15MB-15MB/14MB-14MB-14MB over 20)
      ...
      * com.coulombtech / u0a106 / v26:
               TOTAL: 0.01%
            Receiver: 0.01%
            (Cached): 21% (4.9MB-5.0MB-5.2MB/3.8MB-3.9MB-4.1MB over 2)
      * com.softcoil.mms / u0a86 / v32:
               TOTAL: 0.01%
            (Cached): 0.25%
      * com.udemy.android / u0a91 / v38:
               TOTAL: 0.01%
            Receiver: 0.01%
            (Cached): 0.75% (9.8MB-9.8MB-9.8MB/8.5MB-8.5MB-8.5MB over 1)
      ...
    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은 개발자 자신의 프로세스만 사용하는 메모리입니다. 이 메모리는 앱의 프로세스를 삭제할 때 시스템에서 확보할 수 있는 분량의 RAM입니다. 일반적으로 이 메모리에서 가장 중요한 부분은 개인 더티 RAM으로, 개발자 자신의 프로세스만이 이 메모리를 사용하고 그 콘텐츠는 RAM에만 존재하여 스토리지로 페이징할 수 없기 때문에(Android는 스왑을 사용하지 않음) 가장 비용이 높은 메모리입니다. 개발자가 지정하는 모든 Dalvik 및 네이티브 힙 할당은 개인 더티 RAM이 되고, Zygote 프로세스와 공유하는 Dalvik 및 네이티브 할당은 공유 더티 RAM이 됩니다.
PSS(Proportional Set Size)
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
    

다음은 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 TotalPrivate Dirty 열에만 신경을 쓰면 됩니다. 경우에 따라서는 Private CleanHeap Alloc 열에서도 흥미로운 데이터를 볼 수 있습니다. 잘 관찰해 봐야 할 다른 메모리 할당에 대한 추가 정보(행)는 다음과 같습니다.

Dalvik Heap
앱에서 Dalvik 할당이 사용하는 RAM입니다. Pss Total은 모든 Zygote 할당을 포함합니다(위의 PSS 정의에서 설명한 것처럼, 프로세스 전반의 공유로 가중치가 부여됨). Private Dirty 수는 앱의 힙에만 커밋된 실제 RAM으로, 자체적인 할당과 Zygote에서 앱의 프로세스를 분기한 후로 수정된 모든 Zygote 할당 페이지로 구성됩니다.

참고: Dalvik Other 섹션이 있는 새로운 플랫폼 버전에서는 Dalvik 힙에 관한 Pss TotalPrivate Dirty 수에 JIT(just-in-time) 컴파일 및 GC 기록 관리와 같은 Dalvik 오버헤드가 포함되지 않는 반면, 이전 버전에서는 Dalvik 아래의 총 오버헤드가 모두 나열됩니다.

Heap Alloc은 Dalvik 및 네이티브 힙 할당자가 앱에서 추적하는 메모리의 크기입니다. 이 값은 Pss TotalPrivate Dirty보다 큰데, 그 이유는 프로세스가 Zygote에서 분기되었고 다른 모든 프로세스와 공유하는 할당을 포함하기 때문입니다.

.so mmap.dex mmap
매핑된 .so(네이티브) 및 .dex(Dalvik 또는 ART) 코드용으로 사용 중인 RAM입니다. Pss Total 수에는 여러 앱 사이에서 공유되는 플랫폼 코드가 포함됩니다. Private Clean은 개발자 앱 자체의 코드입니다. 일반적으로, 실제 매핑되는 크기는 훨씬 더 큽니다. 여기서 RAM은 앱에서 실행한 코드와 관련해 현재 RAM에 있어야 하는 부분뿐입니다. 하지만 .so mmap에는 큰 개인 더티 RAM이 있는데, 이는 최종 주소로 로드될 때 네이티브 코드를 수정했기 때문입니다.
.oat mmap
코드 이미지가 사용하는 RAM의 크기입니다. 코드 이미지는 여러 앱에서 공통적으로 사용하는 미리 로드된 클래스를 기반으로 합니다. 이 이미지는 모든 앱 사이에서 공유되며 특정 앱의 영향을 받지 않습니다.
.art mmap
힙 이미지가 사용하는 RAM의 크기입니다. 힙 이미지는 여러 앱에서 공통적으로 사용하는 미리 로드된 클래스를 기반으로 합니다. 이 이미지는 모든 앱 사이에서 공유되며 특정 앱의 영향을 받지 않습니다. ART 이미지는 Object 인스턴스를 포함하고 있지만 힙 크기에는 계산에 넣지 않습니다.
.Heap(-d 플래그를 포함한 경우만)
앱의 힙 메모리 크기입니다. 이 할당에서는 이미지에 있는 개체와 큰 개체의 공간은 제외하지만, zygote 공간과 이동하지 않는 공간은 포함합니다.
.LOS(-d 플래그를 포함한 경우만)
ART 대형 개체 공간에서 사용되는 RAM의 크기입니다. 이는 zygote 대형 개체를 포함합니다. 큰 개체는 12KB보다 큰 완전 원시 배열 할당입니다.
.GC(-d 플래그를 포함한 경우만)
가비지 컬렉션의 오버헤드 비용입니다. 실제로는 이 오버헤드를 줄일 방법이 없습니다.
.JITCache(-d 플래그를 포함한 경우만)
JIT 데이터 및 코드 캐시가 사용하는 메모리의 크기입니다. 일반적으로는 설치 시점에 모든 앱이 컴파일될 것이므로 이 값은 0입니다.
.Zygote(-d 플래그를 포함한 경우만)
zygote 공간에서 사용되는 메모리의 크기입니다. zygote 공간은 기기 시작 중에 생성되며 이 공간에는 결코 할당되지 않습니다.
.NonMoving(-d 플래그를 포함한 경우만)
ART 비이동 공간에서 사용되는 RAM의 크기입니다. 비이동 공간에는 필드와 메서드 같이 이동할 수 없는 특수한 개체가 포함됩니다. 앱에서 사용하는 필드와 메서드 수를 줄여 이 부분을 줄일 수 있습니다.
.IndirectRef(-d 플래그를 포함한 경우만)
ART 간접 참조 테이블에서 사용되는 RAM의 크기입니다. 이 크기는 대개 작지만, 너무 높은 값일 경우 사용하는 로컬 및 전역 JNI 참조의 수를 줄여 크기를 줄일 수 있습니다.
Unknown
시스템에서 더 구체적인 다른 항목 중 하나로 분류할 수 없는 RAM 페이지입니다. 현재, 이 페이지에는 ASLR(Address Space Layout Randomization)로 인해 이 데이터를 수집할 때 도구가 식별할 수 없는 네이티브 할당이 주로 포함되어 있습니다. Dalvik 힙과 마찬가지로, Unknown의 Pss Total에서는 Zygote와의 공유를 고려하고 Private Dirty는 개발자 자신의 앱에만 전용으로 사용되는 알 수 없는 RAM입니다.
TOTAL
프로세스에서 사용하는 총 PSS(Proportional Set Size) RAM입니다. 이는 프로세스에 해당하는 모든 PSS 필드의 합입니다. 즉, 프로세스의 전체 메모리 가중치를 나타내며, 다른 프로세스 및 사용 가능한 총 RAM과 직접 비교할 수 있습니다.

Private DirtyPrivate Clean은 프로세스 내부의 전체 할당으로, 다른 프로세스와는 공유되지 않습니다. 이와 함께(특히 Private Dirty), TOTAL은 프로세스를 삭제할 때 시스템에서 다시 확보하게 되는 RAM의 크기입니다. 더티 RAM은 수정된 페이지이므로 RAM에 커밋된 상태를 유지해야 합니다(스왑이 없음). 반면 클린 RAM은 영구적 파일에서 매핑된 페이지(예: 실행 중인 코드)이므로 얼마 동안 사용하지 않을 경우 페이지 아웃될 수 있습니다.

ViewRootImpl
프로세스에서 활성 상태인 루트 뷰의 개수입니다. 각 루트 뷰는 창과 연결되어 있으므로, 대화상자나 다른 창과 관련된 메모리 누수를 식별하는 데 도움이 될 수 있습니다.

AppContextsActivities
현재 프로세스에서 활성화된 앱 ContextActivity 개체의 개수입니다. 이는 (흔히 있는 일이지만) 정적 참조로 인해 가비지를 수집할 수 없는 누수된 Activity 개체를 빠르게 식별하는 데 도움이 될 수 있습니다. 이러한 개체에는 다른 할당이 다수 연결되어 있는 경우가 많으므로 큰 메모리 누수를 추적하기에 좋은 방법입니다.

참고: View 또는 Drawable 개체에는 자신의 시작 위치인 Activity에 대한 참조도 포함되어 있으므로, View 또는 Drawable 개체를 포함하고 있을 때도 앱에서 Activity 누수가 발생할 수 있습니다.