こんにちは。菊地です。
前回の記事(Android Studio でのメモリ解析の方法 - 株式会社ネクスト エンジニアBlog)で、AndroidStudioにおけるメモリ解析についてまとめましたが、今回はその補足のような記事になります。
AndroidStudio でメモリ関連の調査を行う際に便利だなと思った機能がありましたので、そちらのご紹介になります。
今回は AndroidStudio (Android DDMSかもしれませんが)にある
- Graphics Acceleration の情報を確認するための Graphics States
- ActivityManagerの状態を確認するための Activity Manager State
という2つの機能について記事にさせていただきます。
※ここからは、サンプルとして Navigation Drawer Activity を新規プロジェクトとして作成しています
Graphics State
どうやって使うの?
AndroidStudio > Android DDMS で左側のウィンドウに表示されているパッケージ名から調べたいパッケージ名を指定します。 パッケージを指定したあと Android DDMS > System Information > Graphics States で使えます
何がみれるの?
Graphics State という名前のとおり、現在のアプリにおける描画の状態が確認できます
- どのような描画命令が行われたのか?
- 描画時に使われたメモリ量(現在/最大)
- 描画されたViewの数、メモリおよび描画フレーム数
Applications Graphics Acceleration Info: Uptime: 610094 Realtime: 610094 ** Graphics info for pid 2096 [jp.nextgroup.myapplication] **
Recent DisplayList operations
どのような描画命令が行われたかを一覧で見ることができます
Recent DisplayList operations
DrawDisplayList
DrawPatch
DrawRect
DrawRect
DrawRect
DrawPatch
DrawPatch
SetupShader
DrawRect
ResetShader
DrawDisplayList
DrawDisplayList
DrawDisplayList
Save
ClipRect
DrawDisplayList
DrawDisplayList
RestoreToCount
DrawRect
Save
DrawDisplayList
DrawRect
DrawDisplayList
DrawPatch
Save
ClipRect
Translate
DrawText
RestoreToCount
DrawDisplayList
Save
ClipRect
Translate
DrawText
RestoreToCount
DrawDisplayList
Save
ClipRect
Translate
DrawText
RestoreToCount
RestoreToCount
DrawPatch
DrawDisplayList
DrawPatch
DrawRect
DrawRect
DrawRect
DrawPatch
DrawPatch
Caches
描画命令における
- 現在のメモリ使用量
- 描画に使用された合計メモリ量
を確認することができます
Caches: Current memory usage / total memory usage (bytes): TextureCache 167952 / 25165824 LayerCache 0 / 16777216 RenderBufferCache 0 / 2097152 GradientCache 0 / 524288 PathCache 0 / 10485760 TextDropShadowCache 0 / 2097152 PatchCache 1472 / 131072 FontRenderer 0 A8 524288 / 524288 FontRenderer 0 RGBA 0 / 0 FontRenderer 0 total 524288 / 524288 Other: FboCache 0 / 16 Total memory usage: 693712 bytes, 0.66 MB
View Hierarchy
Viewの描画に関する
- 描画されたViewの数
- Viewの描画に使われているメモリ使用量
- Viewの描画にかかったフレーム数
といった情報を見ることができます
Profile data in ms:
jp.nextgroup.myapplication/jp.nextgroup.myapplication.MyActivity/android.view.ViewRootImpl@52876bc0
View hierarchy:
jp.nextgroup.myapplication/jp.nextgroup.myapplication.MyActivity/android.view.ViewRootImpl@52876bc0
24 views, 2.55 kB of display lists, 19 frames rendered
Total ViewRootImpl: 1
Total Views: 24
Total DisplayList: 2.55 kB
Activity Manager State
どうやって使うの?
AndroidStudio > Android DDMS で左側のウィンドウに表示されているパッケージ名から調べたいパッケージ名を指定します。 パッケージを指定したあと Android DDMS > System Information > Graphics States で使えます
何が見れるの?
現在のアプリにおける ActivityManagerの状態を見る事が出来ます
- Activity の情報
- Activity に Attach されている Fragment
- Fragment の情報
- Viewの階層構造
などなど
Fragmentの状態なども視覚的に確認することができ、Fragmentが破棄されているのかどうか?といったことも確認することができて、とても便利でした。
TASK jp.nextgroup.myapplication id=4
ACTIVITY jp.nextgroup.myapplication/.MyActivity 52a1a528 pid=2096
Local Activity 52852ee4 State:
mResumed=true mStopped=false mFinished=false
mLoadersStarted=true
mChangingConfigurations=false
mCurrentConfig={1.0 ?mcc?mnc en_US ldltr sw360dp w360dp h567dp 480dpi nrml port finger qwerty/v/v dpad/v s.5}
Active Fragments in 52852f64:
#0: NavigationDrawerFragment{5287b3b8 #0 id=0x7f080002}
mFragmentId=#7f080002 mContainerId=#7f080000 mTag=null
mState=5 mIndex=0 mWho=android:fragment:0 mBackStackNesting=0
mAdded=true mRemoving=false mResumed=true mFromLayout=true mInLayout=true
mHidden=false mDetached=false mMenuVisible=true mHasMenu=true
mRetainInstance=false mRetaining=false mUserVisibleHint=true
mFragmentManager=FragmentManager{52852f64 in MyActivity{52852ee4}}
mActivity=jp.nextgroup.myapplication.MyActivity@52852ee4
mView=android.widget.ListView{528798c8 VFED.VC. ........ 0,0-720,1557 #7f080002 app:id/navigation_drawer}
#1: PlaceholderFragment{52862068 #1 id=0x7f080001}
mFragmentId=#7f080001 mContainerId=#7f080001 mTag=null
mState=5 mIndex=1 mWho=android:fragment:1 mBackStackNesting=0
mAdded=true mRemoving=false mResumed=true mFromLayout=false mInLayout=false
mHidden=false mDetached=false mMenuVisible=true mHasMenu=false
mRetainInstance=false mRetaining=false mUserVisibleHint=true
mFragmentManager=FragmentManager{52852f64 in MyActivity{52852ee4}}
mActivity=jp.nextgroup.myapplication.MyActivity@52852ee4
mArguments=Bundle[{section_number=1}]
mContainer=android.widget.FrameLayout{5287ad2c V.E..... ........ 0,0-1080,1557 #7f080001 app:id/container}
mView=android.widget.RelativeLayout{5285b990 V.E..... ........ 0,0-1080,1557}
Added Fragments:
#0: NavigationDrawerFragment{5287b3b8 #0 id=0x7f080002}
#1: PlaceholderFragment{52862068 #1 id=0x7f080001}
Fragments Created Menus:
#0: NavigationDrawerFragment{5287b3b8 #0 id=0x7f080002}
FragmentManager misc state:
mActivity=jp.nextgroup.myapplication.MyActivity@52852ee4
mContainer=android.app.Activity$1@52852fa0
mCurState=5 mStateSaved=false mDestroyed=false
ViewRoot:
mAdded=true mRemoved=false
mConsumeBatchedInputScheduled=false
mPendingInputEventCount=0
mProcessInputEventsScheduled=false
mTraversalScheduled=false
android.view.ViewRootImpl$NativePreImeInputStage: mQueueLength=0
android.view.ViewRootImpl$ImeInputStage: mQueueLength=0
android.view.ViewRootImpl$NativePostImeInputStage: mQueueLength=0
Choreographer:
mFrameScheduled=false
mLastFrameTime=592749 (15996 ms ago)
View Hierarchy:
com.android.internal.policy.impl.PhoneWindow$DecorView{52853760 V.E..... R....... 0,0-1080,1776}
com.android.internal.widget.ActionBarOverlayLayout{52853f34 V.ED.... ........ 0,0-1080,1776 #1020313 android:id/action_bar_overlay_layout}
android.widget.FrameLayout{52855914 V.E..... ........ 0,219-1080,1776 #1020002 android:id/content}
android.support.v4.widget.DrawerLayout{528758b8 VFE..... .F...... 0,0-1080,1557 #7f080000 app:id/drawer_layout}
android.widget.FrameLayout{5287ad2c V.E..... ........ 0,0-1080,1557 #7f080001 app:id/container}
android.widget.RelativeLayout{5285b990 V.E..... ........ 0,0-1080,1557}
android.widget.TextView{52875bc0 V.ED.... ......ID 48,48-48,105 #7f080003 app:id/section_label}
android.widget.ListView{528798c8 VFED.VC. ........ 0,0-720,1557 #7f080002 app:id/navigation_drawer}
android.widget.TextView{52852058 V.ED.... .....A.. 0,0-720,144 #1020014 android:id/text1}
android.widget.TextView{52876384 V.ED.... ........ 0,143-720,287 #1020014 android:id/text1}
android.widget.TextView{528794ac V.ED.... ........ 0,286-720,430 #1020014 android:id/text1}
com.android.internal.widget.ActionBarContainer{52855b94 V.ED.... ........ 0,75-1080,219 #1020314 android:id/action_bar_container}
com.android.internal.widget.ActionBarView{5285b218 V.E..... ........ 0,0-1080,144 #1020315 android:id/action_bar}
android.widget.LinearLayout{5285b5b0 VFE...C. ........ 0,0-531,144}
com.android.internal.widget.ActionBarView$HomeView{5285fb5c V.E..... ........ 0,0-145,144}
android.widget.ImageView{5285fdb4 V.ED.... ........ 0,48-48,96 #102025a android:id/up}
android.widget.ImageView{528614a4 V.ED.... ........ 37,24-133,120 #102002c android:id/home}
android.widget.LinearLayout{52861ee4 V.E..... ........ 145,35-531,108}
android.widget.TextView{52862120 V.ED.... ........ 0,0-362,73 #1020265 android:id/action_bar_title}
android.widget.TextView{52862790 G.ED.... ......I. 0,0-0,0 #1020266 android:id/action_bar_subtitle}
com.android.internal.view.menu.ActionMenuView{5284cd88 V.ED.... ........ 912,0-1080,144}
com.android.internal.view.menu.ActionMenuPresenter$OverflowMenuButton{52848a78 VFED..C. ........ 0,0-168,144}
com.android.internal.widget.ActionBarContextView{52862afc G.E..... ......ID 0,0-0,0 #1020316 android:id/action_context_bar}
com.android.internal.widget.ActionBarContainer{528680e8 G.ED.... ......ID 0,0-0,0 #1020317 android:id/split_action_bar}
Looper (main, tid 1) {5284fff0}
(Total messages: 0, idling=false, quitting=false)
まとめ
Graphics Manager は描画命令を視覚的に確認できるほか、メモリ使用量のほか描画にかかったフレームなども見る事ができます。 そのため、 描画が遅い? と思ったときや、 なんか重くなった! 描画重い!? と嘆く前にこれを使い、実際にどういったことが行われて、どの程度の時間がかかっているのかを確認することで、少しでも操作を快適にできるかもしれません。
Activity Manager State もライフサイクルが複雑なFragmentについて、実際の状態を確認することができますし、実は裏でFragmentが生き残っていた!!なんてことも防げるようになると思います。
こういったツールも使いながら少しでもいいアプリを提供できるようにしていけたらと思います。