【Kotlin/Android】Memory Profilerの使い方!コードでメモリ消費量を取得するには?

【Kotlin/Android】Memory Profilerの使い方!コードでメモリ消費量を取得するには?

この記事からわかること

  • Android Studio/KotlinMemory Profiler使い方
  • CPU/Memory/Energy使用量するには?
  • コードからメモリ消費量取得するには?
  • Runtime.getRuntimetotalMemoryfreeMemoryの使い方
  • ガーベジコレクションをコードから実行する方法
  • OOM(OutOfMemory)対策

index

[open]

\ アプリをリリースしました /

みんなの誕生日

友達や家族の誕生日をメモ!通知も届く-みんなの誕生日-

posted withアプリーチ

環境

Android Profiler

公式リファレンス:Memory Profiler を使用してアプリのメモリ使用量を調べる

起動しているアプリのメモリ消費量を確認できる「Memory Profiler」はAndroid Studioの機能の「Android Profiler」から提供されている1つで、アプリのメモリ消費量などを確認することができます。これは実機へビルドしてテストしている場合に利用することができます。

Android Profiler

Android Profilerを起動させるには上部メニュー「View」 > 「Tool Windows」 > 「Profiler」をクリックします(Android Studioボトムバーの「Profiler」からでも表示できます)。起動させると以下のように上からCPU/Memory/Energyの使用量が可視化されて表示されるようになります。

【Kotlin/Android】LeakCanaryでメモリリークを検知する方法!

メモリリークが発生している場合はこのMemoryの使用量が減らずにどんどん増えていくような挙動になります。

Memory Profiler

メモリ部分をクリックすると「Memory Profiler」が起動します。表示されているメモリは7種類のカテゴリに分けられてスタックされます。またゴミ箱アイコンをクリックすることで明示的にガーベジコレクションを実行させることが可能です。

【Kotlin/Android】Memory Profilerの使い方!コードでメモリ消費量を取得するには?

Others

アプリによって使用された、カテゴリが不明なメモリ。

Code

dexバイトコード、最適化またはコンパイルされた dex コード、.so ライブラリ、フォントなど、コードとリソースのためにアプリが使用したメモリ。

Stack

アプリのネイティブスタックとJavaスタックの両方によって使用されたメモリ。通常、アプリが実行しているスレッドの数に関係する。

Graphics

GLサーフェスやGLテクスチャなど画面にピクセルを表示するためにグラフィックバッファキューに使用されたメモリ。

Native

C / C++ のコードから割り当てられたオブジェクトのメモリ。

※コードを Java または Kotlin で記述していても、画像アセットやグラフィックを処理など一部の実装はネイティブメモリを使用するためC / C++での記述がなくても表示される

Java

Java / Kotlin のコードから割り当てられたオブジェクトのメモリ。

Allocated

アプリによって割り当てられた Java / Kotlin オブジェクトの数。C または C++ で割り当てられたオブジェクトはカウントされない。

Kotlinでメモリ消費量を取得する

Kotlinのコードから現在消費しているメモリ量を取得するにはRuntimeクラスを使用します。totalMemory割り当て済みのメモリfreeMemory空きメモリ量を取得することが可能です。

fun getMemoryUsage() {
    val runtime = Runtime.getRuntime()
    val totalMemory = runtime.totalMemory()   // 現在の割り当て済みメモリ量
    val freeMemory = runtime.freeMemory()     // 現在の空きメモリ量
    val usedMemory = totalMemory - freeMemory // 使用中のメモリ量
    Log.d("Memory", "メモリ消費量:${usedMemory}") // メモリ消費量:15200776
}

メモリ量を取得する

端末のメモリ量はmaxMemoryメソッドで取得できます。

fun getMemoryUsage() {
    val runtime = Runtime.getRuntime()
    val maxMemory = runtime.maxMemory()
    Log.d("Memory", "メモリ量:${maxMemory}") // メモリmax:201326592
}

ActivityManagerからも取得できるようです。

val am = getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
val largeMemory = am.largeMemoryClass
Log.d("Memory", "メモリ量:${largeMemory}") // メモリ量:512

メモリの確保や解放のタイミングや強参照/弱参照については以下の記事を参考にしてください。

コードからガーベジコレクションを実行する

Kotlinのコードからガーベジコレクションを実行するにはSystem.gc()を使用します。ですがこれはガベージコレクタに対してガベージコレクションの実行要求を送るだけであり、すぐさまガベージコレクションが実行されることは保証されないので注意してください。

System.gc()

OOM対策でヒープ領域を増やす

公式リファレンス:android:largeHeap

処理が非常に重くメモリを大量消費するアプリではOOM(OutOfMemory)エラーが発生することが多くなります。基本的にはアプリのパフォーマンスを改善する必要がありますが、どうしても改善しない場合の苦肉の策としてヒープ領域を拡大する設定がありました。

マニフェストファイルのandroid:largeHeap属性にtrueを渡すことでヒープ領域を拡大することができるようです。

<application
    android:largeHeap="true" >
</appplication>

ただし設定することでガーベジコレクションに時間がかかるようになるなどデメリットもあるようなので使い所には注意が必要です。

What are the downsides of using android:largeHeap="true"?

まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。

ご覧いただきありがとうございました。

searchbox

スポンサー

ProFile

ame

趣味:読書,プログラミング学習,サイト制作,ブログ

IT嫌いを克服するためにITパスを取得しようと勉強してからサイト制作が趣味に変わりました笑
今はCMSを使わずこのサイトを完全自作でサイト運営中〜

New Article

index