dumpsys
는 Android 기기에서 실행되는 도구로, 시스템 서비스에 관한 정보를 제공합니다. Android 디버그 브리지(ADB)를 사용해 명령줄에서 dumpsys
를 호출하여 연결된 기기에서 실행되는 모든 시스템 서비스의 진단 출력을 가져올 수 있습니다.
이 출력은 일반적으로 원하는 것보다 상세하므로 이 페이지의 명령줄 옵션을 사용하여 원하는 시스템 서비스의 출력만 가져옵니다. 이 페이지에서는 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
|
출력에 포함하지 않을 services를 지정합니다. |
service [arguments]
|
출력하려는 service를 지정합니다. 일부 서비스에서는 선택적 arguments를 전달할 수도 있습니다. 자세히 알아보기 위해
이러한 선택적 인수는 -h 옵션을
서비스:
adb shell dumpsys procstats -h |
-c
|
특정 서비스를 지정할 때는 이 옵션을 추가하여 기기에서 처리하기 쉬운 형식으로 데이터를 출력하세요. |
-h
|
특정 서비스의 경우 이 옵션을 추가하여 서비스의 도움말 텍스트와 추가 옵션을 볼 수 있습니다. |
입력 진단 검사
다음 명령어와 같이 input
서비스를 지정하면 키보드, 터치스크린과 같은 시스템 입력 장치의 상태와 입력 이벤트 처리를 덤프합니다.
adb shell dumpsys input
출력은 연결된 기기에서 실행되는 Android 버전에 따라 달라집니다. 다음 섹션에서는 일반적으로 표시되는 정보의 유형을 설명합니다.
이벤트 허브 상태
다음은 입력 진단의 이벤트 허브 상태를 검사할 때 표시될 수 있는 내용의 샘플입니다.
INPUT MANAGER (dumpsys input) Event Hub State: BuiltInKeyboardId: -2 Devices: -1: Virtual Classes: 0x40000023 Path:Descriptor: a718a782d34bc767f4689c232d64d527998ea7fd Location: ControllerNumber: 0 UniqueId: Identifier: bus=0x0000, vendor=0x0000, product=0x0000, version=0x0000 KeyLayoutFile: /system/usr/keylayout/Generic.kl KeyCharacterMapFile: /system/usr/keychars/Virtual.kcm ConfigurationFile: HaveKeyboardLayoutOverlay: false 1: msm8974-taiko-mtp-snd-card Headset Jack Classes: 0x00000080 Path: /dev/input/event5 Descriptor: c8e3782483b4837ead6602e20483c46ff801112c Location: ALSA ControllerNumber: 0 UniqueId: Identifier: bus=0x0000, vendor=0x0000, product=0x0000, version=0x0000 KeyLayoutFile: KeyCharacterMapFile: ConfigurationFile: HaveKeyboardLayoutOverlay: false 2: msm8974-taiko-mtp-snd-card Button Jack Classes: 0x00000001 Path: /dev/input/event4 Descriptor: 96fe62b244c555351ec576b282232e787fb42bab Location: ALSA ControllerNumber: 0 UniqueId: Identifier: bus=0x0000, vendor=0x0000, product=0x0000, version=0x0000 KeyLayoutFile: /system/usr/keylayout/msm8974-taiko-mtp-snd-card_Button_Jack.kl KeyCharacterMapFile: /system/usr/keychars/msm8974-taiko-mtp-snd-card_Button_Jack.kcm ConfigurationFile: HaveKeyboardLayoutOverlay: false 3: hs_detect Classes: 0x00000081 Path: /dev/input/event3 Descriptor: 485d69228e24f5e46da1598745890b214130dbc4 Location: ControllerNumber: 0 UniqueId: Identifier: bus=0x0000, vendor=0x0001, product=0x0001, version=0x0001 KeyLayoutFile: /system/usr/keylayout/hs_detect.kl KeyCharacterMapFile: /system/usr/keychars/hs_detect.kcm ConfigurationFile: HaveKeyboardLayoutOverlay: false ...
입력 리더 상태
InputReader
는 커널의 입력 이벤트를 디코딩합니다. 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
가 정확합니다. 기기에 내장 키보드가 없다면 ID는-2
여야 합니다. 그렇지 않으면 내장 키보드의 ID여야 합니다. BuiltInKeyboardId
가-2
여야 하는데 그렇지 않다면 특수 기능 키패드의 키 문자 맵 파일이 누락된 것입니다. 특수 기능 키패드 기기에는type SPECIAL_FUNCTION
줄만 포함된 키 문자 맵 파일이 있어야 합니다.
입력 리더 상태:
- 일반적인 모든 입력 장치가 포함되어 있습니다.
- 각 입력 장치가 정확히 구성되어 있습니다. 특히 터치스크린 및 조이스틱 축이 정확히 구성되어 있는지 확인하세요.
입력 디스패처 상태:
- 모든 입력 이벤트가 예상대로 처리됩니다.
- 터치스크린을 터치하고
dumpsys
를 동시에 실행하면TouchStates
줄이 터치하고 있는 창을 정확하게 식별합니다.
UI 성능 테스트
gfxinfo
서비스를 지정하면 기록 단계 중에 발생하는 애니메이션 프레임과 관련된 성능 정보와 함께 출력이 제공됩니다.
다음 명령어는 gfxinfo
를 사용하여 지정된 패키지 이름의 UI 성능 데이터를 수집합니다.
adb shell dumpsys gfxinfo package-name
framestats
옵션을 포함하여 최근 프레임의 더 자세한 프레임 타이밍 정보를 제공할 수도 있으므로 아래와 같이 문제를 더 정확하게 추적하고 디버그할 수 있습니다.
adb shell dumpsys gfxinfo package-name framestats
gfxinfo
와 framestats
를 사용하여 UI 성능 측정값을 테스트에 통합하는 방법에 관한 자세한 내용은 Macrobenchmark 작성을 참고하세요.
네트워크 진단 검사
netstats
서비스를 지정하면 이전 기기가 부팅되었을 때부터 수집된 네트워크 사용 통계가 제공됩니다. 자세한 순 사용자 ID(UID) 정보와 같은 추가 정보를 출력하려면 다음과 같이 detail
옵션을 포함하세요.
adb shell dumpsys netstats detail
출력은 연결된 기기에서 실행되는 Android 버전에 따라 달라집니다. 다음 섹션에서는 일반적으로 표시되는 정보의 유형을 설명합니다.
활성 인터페이스 및 활성 UID 인터페이스
다음 샘플 출력은 연결된 기기의 활성 인터페이스와 활성 UID 인터페이스를 표시합니다. 대부분의 경우 활성 인터페이스와 활성 UID 인터페이스의 정보는 동일합니다.
Active interfaces: iface=wlan0 ident=[{type=WIFI, subType=COMBINED, networkId="Guest"}] Active UID interfaces: iface=wlan0 ident=[{type=WIFI, subType=COMBINED, networkId="Guest"}]
'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
은 트래픽과 연결된 소켓 태그를 나타냅니다.rxBytes
와rxPackets
는 상응하는 시간 간격에 수신된 바이트 및 패킷을 나타냅니다.txBytes
와txPackets
는 상응하는 시간 간격에 전송된 바이트 및 패킷을 나타냅니다.
배터리 진단 검사
batterystats
서비스를 지정하면 순 사용자 ID(UID)로 구성된 기기의 배터리 사용량에 관한 통계 데이터가 생성됩니다. dumpsys
를 사용하여 앱의 잠자기 및 앱 대기 모드를 테스트하는 방법에 관한 자세한 내용은 잠자기 및 앱 대기 모드로 테스트를 참고하세요.
batterystats
의 명령어는 다음과 같습니다.
adb shell dumpsys batterystats options
batterystats
에 사용 가능한 추가 옵션 목록을 확인하려면 -h
옵션을 포함하세요. 다음 예는 기기가 마지막으로 충전된 후 지정된 앱 패키지의 배터리 사용량 통계를 출력합니다.
adb shell dumpsys batterystats --charged package-name
일반적으로 출력에는 다음이 포함됩니다.
- 배터리 관련 이벤트 내역
- 기기의 전역 통계
- UID 및 시스템 구성요소당 대략적인 전력 사용
- 각 앱의 패킷당 모바일 밀리초
- 집계된 시스템 UID 통계
- 집계된 앱 UID 통계
배터리 관련 문제를 더 쉽게 파악하고 진단할 수 있도록 하는 batterystats
사용과 출력의 HTML 시각화 생성에 관한 자세한 내용은 Batterystats와 Battery Historian으로 배터리 사용량 프로파일링을 참고하세요.
머신 친화적인 출력 검사
다음 명령어를 사용하여 기기에서 읽을 수 있는 CSV 형식으로 batterystats
출력을 생성할 수 있습니다.
adb shell dumpsys batterystats --checkin
다음은 출력의 예입니다.
9,0,i,vers,11,116,K,L 9,0,i,uid,1000,android 9,0,i,uid,1000,com.android.providers.settings 9,0,i,uid,1000,com.android.inputdevices 9,0,i,uid,1000,com.android.server.telecom ... 9,0,i,dsd,1820451,97,s-,p- 9,0,i,dsd,3517481,98,s-,p- 9,0,l,bt,0,8548446,1000983,8566645,1019182,1418672206045,8541652,994188 9,0,l,gn,0,0,666932,495312,0,0,2104,1444 9,0,l,m,6794,0,8548446,8548446,0,0,0,666932,495312,0,697728,0,0,0,5797,0,0 ...
배터리 사용량 관찰은 UID 또는 시스템 수준별로 표시될 수 있습니다. 데이터는 배터리 성능 분석에 유용한 정도에 따라 선택되어 포함됩니다. 각 행은 다음 요소가 있는 관찰값을 나타냅니다.
- 자리표시자 정수
- 관찰과 연결된 사용자 ID
- 집계 모드:
i
: 충전/미충전 상태와 관련 없는 정보l
:--charged
(마지막으로 충전한 이후 사용량)u
:--unplugged
(마지막으로 연결 해제한 이후 사용량). Android 5.1.1에서 지원 중단됨
- 줄의 후속값 해석 방법을 결정하는 섹션 식별자
다음 표에는 표시될 수 있는 다양한 섹션 식별자가 설명되어 있습니다.
섹션 식별자 | 설명 | 남은 필드 |
---|---|---|
|
버전 |
|
|
UID |
|
|
APK |
|
|
프로세스 |
|
|
센서 |
|
|
바이브레이터 |
|
|
포그라운드 |
|
|
상태 시간 |
|
|
wake lock |
|
|
동기화 |
|
|
작업 |
|
|
커널 wake lock |
|
|
wakeup 이유 |
|
|
네트워크 |
|
|
사용자 활동 |
|
|
배터리 |
|
|
배터리 사용량 |
|
|
배터리 잔량 |
|
|
Wi-Fi |
|
|
전역 Wi-Fi |
|
|
전역 블루투스 |
|
|
기타 |
|
|
전역 네트워크 |
|
|
화면 밝기 |
|
|
신호 스캐닝 시간 |
|
|
신호 강도 시간 |
|
|
신호 강도 횟수 |
|
|
데이터 연결 시간 |
|
|
데이터 연결 횟수 |
|
|
Wi-Fi 상태 시간 |
|
|
Wi-Fi 상태 횟수 |
|
|
Wi-Fi 서플리컨트 상태 시간 |
|
|
Wi-Fi 서플리컨트 상태 횟수 |
|
|
Wi-Fi 신호 강도 시간 |
|
|
Wi-Fi 신호 강도 횟수 |
|
|
블루투스 상태 시간 |
|
|
블루투스 상태 횟수 |
|
|
전원 사용 요약 |
|
|
전원 사용 항목 |
|
|
사용 단계 |
|
|
충전 단계 |
|
|
남은 사용 시간 |
|
|
남은 충전 시간 |
|
참고: Android 6.0 전에는 블루투스 라디오, 무선 라디오, Wi-Fi의 전원 사용이 m
(기타) 섹션 카테고리에서 추적되었습니다. Android 6.0 이상에서는 이러한 구성요소의 전원 사용이 각 구성요소의 개별 라벨(wifi
, blue
, cell
)이 있는 pwi
(전원 사용 항목) 섹션에서 추적됩니다.
메모리 할당 보기
procstats
를 사용하여 일정 기간 동안의 앱 메모리 사용량을 검사하거나 meminfo
를 사용하여 특정 시점에 사용량을 검사할 수 있습니다.
다음 섹션에서는 두 방법을 모두 사용하는 방법을 보여줍니다.
procstats
procstats
를 통해 앱이 백그라운드에서 얼마나 오래 실행되는지, 그 시간 동안 얼마나 많은 메모리를 사용하는지 등 시간이 지남에 따라 앱이 어떻게 동작하는지 확인할 수 있습니다. 이렇게 하면 특히 앱이 메모리가 부족한 기기에서 실행될 때 메모리 누수와 같이 앱의 성능에 영향을 미칠 수 있는 비효율성이나 오동작을 빠르게 찾을 수 있습니다. 상태 덤프는 모든 애플리케이션의 런타임, PSS(Proportional Set Size), USS(Unique Set Size), RSS(Resident Set Size)에 관한 통계를 표시합니다.
사람이 읽을 수 있는 형식으로 지난 3시간 동안의 애플리케이션 메모리 사용량 통계를 가져오려면 다음 명령어를 실행하세요.
adb shell dumpsys procstats --hours 3
다음 예와 같이 출력에는 애플리케이션이 실행된 시간 비율이 표시되고 PSS, USS, RSS가 샘플 수에 관해 minPSS-avgPSS-maxPSS/minUSS-avgUSS-maxUSS/minRSS-avgRSS-maxRSS
로 표시됩니다.
AGGREGATED OVER LAST 3 HOURS: * com.android.systemui / u0a37 / v28: TOTAL: 100% (15MB-16MB-17MB/7.7MB-8.7MB-9.4MB/7.7MB-9.6MB-84MB over 178) Persistent: 100% (15MB-16MB-17MB/7.7MB-8.7MB-9.4MB/7.7MB-9.6MB-84MB over 178) * com.android.se / 1068 / v28: TOTAL: 100% (2.8MB-2.9MB-2.9MB/300KB-301KB-304KB/304KB-22MB-33MB over 3) Persistent: 100% (2.8MB-2.9MB-2.9MB/300KB-301KB-304KB/304KB-22MB-33MB over 3) * com.google.android.gms.persistent / u0a7 / v19056073: TOTAL: 100% (37MB-38MB-40MB/27MB-28MB-29MB/124MB-125MB-126MB over 2) Imp Fg: 100% (37MB-38MB-40MB/27MB-28MB-29MB/124MB-125MB-126MB over 2) ... * com.android.gallery3d / u0a62 / v40030: TOTAL: 0.01% Receiver: 0.01% (Cached): 54% (6.4MB-6.5MB-6.9MB/4.4MB-4.4MB-4.4MB/4.4MB-26MB-68MB over 6) * com.google.android.tvlauncher / u0a30 / v1010900130: TOTAL: 0.01% Receiver: 0.01% (Cached): 91% (5.8MB-13MB-14MB/3.5MB-10MB-12MB/12MB-33MB-78MB over 6) * com.android.vending:instant_app_installer / u0a16 / v81633968: TOTAL: 0.01% Receiver: 0.01% (Cached): 100% (14MB-15MB-16MB/3.8MB-4.2MB-5.1MB/3.8MB-30MB-95MB over 7) ... Run time Stats: SOff/Norm: +32m52s226ms SOn /Norm: +2h10m8s364ms Mod : +17s930ms TOTAL: +2h43m18s520ms Memory usage: Kernel : 265MB (38 samples) Native : 73MB (38 samples) Persist: 262MB (90 samples) Top : 190MB (325 samples) ImpFg : 204MB (569 samples) ImpBg : 754KB (345 samples) Service: 93MB (1912 samples) Receivr: 227KB (1169 samples) Home : 66MB (12 samples) LastAct: 30MB (255 samples) CchAct : 220MB (450 samples) CchCAct: 193MB (71 samples) CchEmty: 182MB (652 samples) Cached : 58MB (38 samples) Free : 60MB (38 samples) TOTAL : 1.9GB ServRst: 50KB (278 samples) Start time: 2015-04-08 13:44:18 Total elapsed time: +2h43m18s521ms (partial) libart.so
meminfo
다음 명령어를 사용하면 다양한 유형의 RAM 할당 사이에서 앱의 메모리가 나뉘는 방법의 스냅샷을 간단히 기록할 수 있습니다.
adb shell dumpsys meminfo package_name|pid [-d]
-d
플래그를 지정하면 Dalvik 및 ART 메모리 사용량과 관련된 더 자세한 정보가 출력됩니다.
출력 결과에는 앱의 현재 할당 메모리가 전부 KB 단위로 나열됩니다.
이 정보를 자세히 검사하려면 다음 유형의 할당을 이해하고 있어야 합니다.
- 개인(클린 및 더티) RAM
- 개인 RAM은 개발자의 프로세스에서만 사용되는 메모리입니다. 이 메모리는 앱의 프로세스가 소멸될 때 시스템에서 확보할 수 있는 분량의 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 Total
및 Private Dirty
열에만 유의하세요.
경우에 따라서는 Private Clean
및 Heap Alloc
열에서도 흥미로운 데이터를 제공합니다.
다음은 관찰해야 하는 다양한 메모리 할당에 관한 자세한 정보를 제공합니다.
Dalvik Heap
- 앱에서 Dalvik 할당에 사용되는 RAM입니다.
Pss Total
에는 PSS 정의에서 설명된 대로 프로세스 간 공유로 가중치가 적용된 모든 Zygote 할당이 포함됩니다.Private Dirty
수는 앱의 힙에만 커밋된 실제 RAM으로, 자체 할당과 Zygote에서 앱의 프로세스를 포크한 이후 수정된 모든 Zygote 할당 페이지로 구성됩니다.참고:
Dalvik Other
섹션이 있는 최신 플랫폼 버전에서 Dalvik 힙의Pss Total
과Private Dirty
수에는 just-in-time 컴파일(JIT)과 GC 기록 관리와 같은 Dalvik 오버헤드가 포함되지 않지만 이전 버전에서는Dalvik
아래 모두 결합되어 나열됩니다.Heap Alloc
은 Dalvik과 네이티브 힙 할당자가 계속 추적하는 앱의 메모리 크기입니다. 이 값은Pss Total
과Private Dirty
보다 큽니다. 프로세스가 Zygote에서 포크되었고 다른 모든 프로세스와 공유하는 할당을 포함하기 때문입니다. .so mmap
및.dex mmap
- 매핑된
.so
(네이티브) 및.dex
(Dalvik 또는 ART) 코드에 사용되는 RAM입니다.Pss Total
수에는 여러 앱에서 공유되는 플랫폼 코드가 포함됩니다.Private Clean
은 앱의 자체 코드입니다. 일반적으로 실제 매핑된 크기가 더 큽니다. 여기서 RAM은 앱에서 실행한 코드의 RAM에만 현재 있어야 하는 것입니다. 그러나.so mmap
에는 큰 비공개 더티가 있으며 이는 최종 주소로 로드될 때 네이티브 코드를 수정했기 때문입니다. .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)으로 인해 이 데이터를 수집할 때 도구에서 식별할 수 없습니다. Dalvik 힙과 마찬가지로
Unknown
의Pss Total
은 Zygote와의 공유를 고려하고Private Dirty
는 앱에만 전용으로 사용되는 알 수 없는 RAM입니다. TOTAL
- 프로세스에서 사용하는 총 PSS(Proportional Set Size) RAM입니다. 이는 프로세스에 해당하는 모든 PSS 필드의 합입니다. 즉, 프로세스의 전체 메모리 가중치를 나타내며 다른 프로세스 및 사용 가능한 총 RAM과 직접 비교할 수 있습니다.
Private Dirty
와Private Clean
은 프로세스 내의 총 할당량이며 다른 프로세스와는 공유되지 않습니다. 프로세스가 소멸되면 이러한 할당의 모든 RAM이 시스템으로 다시 해제됩니다.Private Clean
은 프로세스가 소멸되기 전에 페이지 아웃되고 해제될 수도 있지만Private Dirty
는 프로세스 소멸 시에만 해제됩니다.더티 RAM은 수정된 페이지이므로 RAM에 커밋된 상태를 유지해야 합니다(스왑이 없기 때문). 클린 RAM은 영구 파일에서 매핑된 페이지(예: 실행 중인 코드)이므로 한 동안 사용되지 않으면 페이지 아웃될 수 있습니다.
ViewRootImpl
- 프로세스에서 활성 상태인 루트 뷰의 수입니다. 각 루트 뷰는 창과 연결되어 있으므로, 대화상자나 다른 창과 관련된 메모리 누수를 식별하는 데 도움이 될 수 있습니다.
AppContexts
및Activities
- 현재 프로세스에 있는 앱
Context
및Activity
객체의 수입니다. 일반적으로 정적 참조로 인해 가비지 컬렉션될 수 없는 누수된Activity
객체를 빠르게 식별하는 데 도움이 될 수 있습니다. 이러한 객체에는 다른 할당이 다수 연결되어 있는 경우가 많으므로 큰 메모리 누수를 추적하기에 좋은 방법입니다.