web-dev-qa-db-ja.com

Androidで現在のメモリ使用量を取得する方法は?

/ proc/meminfoを使用し、コマンド応答を解析しました。

MemTotal:94348 kB MemFree:5784 kB

手段。空きメモリが5MBしかないことを示しています。 Androidモバイルで可能ですか?私のモバイルには5〜6個のアプリケーションしかインストールされておらず、他のタスクは実行されていません。それでも、このコマンドは空きメモリが非常に少ないことを示しています。

誰かがこれを明確にすることはできますか?またはAndroidでメモリ使用量を取得する他の方法はありますか?

99
Badal

注意:この回答は、デバイスのメモリ使用量/使用可能量を測定します。これはアプリで利用できるものではありません。 APPが何をしており、許可されていることを測定するには、 Android開発者の回答を使用 にします。


Androidドキュメント-ActivityManager.MemoryInfo

  1. / proc/meminfoコマンドを解析します。参照コードは次の場所にあります。 Androidでメモリ使用量を取得する

  2. 以下のコードを使用して、現在のRAMを取得します。

    MemoryInfo mi = new MemoryInfo();
    ActivityManager activityManager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
    activityManager.getMemoryInfo(mi);
    double availableMegs = mi.availMem / 0x100000L;
    
    //Percentage can be calculated for API 16+
    double percentAvail = mi.availMem / (double)mi.totalMem * 100.0;
    

番号0x100000Lの説明

1024 bytes      == 1 Kibibyte 
1024 Kibibyte   == 1 Mebibyte

1024 * 1024     == 1048576
1048576         == 0x100000

バイトからメビバイトへの変換に数値が使用されていることは明らかです

追伸:合計メモリを1回だけ計算する必要があります。したがって、コードでポイント1を1回だけ呼び出してから、ポイント2のコードを繰り返し呼び出すことができます。

163
Badal

取得するメモリクエリの定義によって異なります。


通常、ヒープメモリの状態を知りたいのは、メモリが多すぎるとOOMが発生してアプリがクラッシュするためです。

このために、次の値を確認できます。

final Runtime runtime = Runtime.getRuntime();
final long usedMemInMB=(runtime.totalMemory() - runtime.freeMemory()) / 1048576L;
final long maxHeapSizeInMB=runtime.maxMemory() / 1048576L;
final long availHeapSizeInMB = maxHeapSizeInMB - usedMemInMB;

「usedMemInMB」変数が「maxHeapSizeInMB」に近づくほど、availHeapSizeInMBがゼロに近づくほど、OOMが近くなります。 (メモリの断片化により、ゼロに達する前にOOMが発生する場合があります。)

これは、メモリ使用量のDDMSツールが示すものでもあります。


あるいは、実際のRAM使用量があります。これは、システム全体がどれだけ使用するかです。 受け入れられた答え を参照して計算してください。


更新:Android OはアプリでネイティブRAM(少なくともビットマップストレージ用であり、通常は大量のメモリ使用量の主な理由)を使用し、ヒープだけでなく、物事が変更され、OOMが少なくなります(ヒープにビットマップが含まれなくなったため、 here )をチェックしますが、メモリリークが疑われる場合は、メモリの使用に注意する必要があります。 Android Oで、古いバージョンでOOMを引き起こすはずだったメモリリークがある場合、それをキャッチできずにクラッシュするようです。メモリ使用量を確認する方法は次のとおりです。

 val nativeHeapSize = Debug.getNativeHeapSize()
 val nativeHeapFreeSize = Debug.getNativeHeapFreeSize()
 val usedMemInBytes = nativeHeapSize - nativeHeapFreeSize
 val usedMemInPercentage = usedMemInBytes * 100 / nativeHeapSize

しかし、グラフを使用してデータをリアルタイムで表示するIDEのプロファイラーを使用するのが最善であると考えています。

Android Oの良いニュースは、あまりにも多くの大きなビットマップを格納するOOMのためにクラッシュを取得するのがはるかに難しいことですが、悪いニュースは、そのようなケースをキャッチすることができないと思うことですランタイム。

73

メモリ使用量を計算する方法を次に示します現在実行中のアプリケーションの

public static long getUsedMemorySize() {

    long freeSize = 0L;
    long totalSize = 0L;
    long usedSize = -1L;
    try {
        Runtime info = Runtime.getRuntime();
        freeSize = info.freeMemory();
        totalSize = info.totalMemory();
        usedSize = totalSize - freeSize;
    } catch (Exception e) {
        e.printStackTrace();
    }
    return usedSize;

}
28
Sharmilee

別の方法(現在、G1で25MBの空き容量を表示しています):

MemoryInfo mi = new MemoryInfo();
ActivityManager activityManager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
activityManager.getMemoryInfo(mi);
long availableMegs = mi.availMem / 1048576L;
17
yanchenko

Linuxのメモリ管理の哲学は、「空きメモリは無駄なメモリです」です。

次の2行は、「バッファ」にあるメモリの量と「キャッシュ」にあるメモリの量を示していると思います。 2つの間に違いがありますが(その違いを尋ねないでください:)、どちらもファイルデータとメタデータをキャッシュするために使用されるメモリの量に大まかに加算されます。

Linuxシステムでメモリを解放するためのはるかに役立つガイドは、free(1)コマンドです。私のデスクトップでは、次のような情報が報告されます。

 $ free -m 
キャッシュされた合計使用済み空き共有バッファー
 Mem:5980 1055 4924 0 91 374 
-/ + buffers/cache:589 5391 
スワップ:6347 0 6347 

+/- buffers/cache:行は魔法の行であり、実際に必要なプロセスメモリは約589メガバイト、91 + 374メガバイトという意味で約5391メガバイトの「空き」メモリがあることを報告しています。他の場所でメモリをより有益に使用できる場合は、バッファ/キャッシュメモリを破棄できます。

(私のマシンは約3時間稼働しており、stackoverflow以外はほとんど何もしていません。そのため、非常に多くの空きメモリがあります。)

Androidにfree(1)が付属していない場合は、/proc/meminfoファイルを使用して自分で計算できます。 free(1)出力形式が好きです。 :)

12
sarnold

私はいくつかの文章を参照します。

参照:

このgetMemorySize()メソッドには、合計および空きメモリサイズを持つMemorySizeが返されます。
このコードは完全には信じられません。
このコードはLG G3 cat.6(v5.0.1)でテストしています

    private MemorySize getMemorySize() {
        final Pattern PATTERN = Pattern.compile("([a-zA-Z]+):\\s*(\\d+)");

        MemorySize result = new MemorySize();
        String line;
        try {
            RandomAccessFile reader = new RandomAccessFile("/proc/meminfo", "r");
            while ((line = reader.readLine()) != null) {
                Matcher m = PATTERN.matcher(line);
                if (m.find()) {
                    String name = m.group(1);
                    String size = m.group(2);

                    if (name.equalsIgnoreCase("MemTotal")) {
                        result.total = Long.parseLong(size);
                    } else if (name.equalsIgnoreCase("MemFree") || name.equalsIgnoreCase("Buffers") ||
                            name.equalsIgnoreCase("Cached") || name.equalsIgnoreCase("SwapFree")) {
                        result.free += Long.parseLong(size);
                    }
                }
            }
            reader.close();

            result.total *= 1024;
            result.free *= 1024;
        } catch (IOException e) {
            e.printStackTrace();
        }

        return result;
    }

    private static class MemorySize {
        public long total = 0;
        public long free = 0;
    }

Pattern.compile()はコストが高いことを知っているので、コードをクラスメンバーに移動できます。

6
Hogun

Androidソースツリーを見ました。

内部com.Android.server.am。ActivityManagerService.Java(Android.app。ActivityManager)によって公開される内部サービス)。

public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
    final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
    final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ);
    outInfo.availMem = Process.getFreeMemory();
    outInfo.totalMem = Process.getTotalMemory();
    outInfo.threshold = homeAppMem;
    outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2));
    outInfo.hiddenAppThreshold = hiddenAppMem;
    outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
            ProcessList.SERVICE_ADJ);
    outInfo.visibleAppThreshold = mProcessList.getMemLevel(
            ProcessList.VISIBLE_APP_ADJ);
    outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
            ProcessList.FOREGROUND_APP_ADJ);
}

Android.os内Process.Java

/** @hide */
public static final native long getFreeMemory();

/** @hide */
public static final native long getTotalMemory();

Android_util_Process.cpp からJNIメソッドを呼び出します

結論

MemoryInfo.availMem = MemFree +/proc/meminfoにキャッシュされます。

Total MemoryはAPIレベル16で追加されます。

3
ragazenta

Android SDK it selfの一部であるDDMSツールを使用することもできます。 Javaコードとネイティブc/c ++コードのメモリ割り当てを取得するのにも役立ちます。

1
vsmph
final long usedMemInMB=(runtime.totalMemory() - runtime.freeMemory()) / 1048576L;
final long maxHeapSizeInMB=runtime.maxMemory() / 1048576L;
final long availHeapSizeInMB = maxHeapSizeInMB - usedMemInMB;

奇妙なコードです。 MaxMemory-(totalMemory-freeMemory)を返します。 freeMemoryが0の場合、コードはMaxMemory-totalMemoryを返すため、0以上になることがあります。freeMemoryが使用されないのはなぜですか?

0
Andrey
public static boolean isAppInLowMemory(Context context) {
    ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
    ActivityManager.MemoryInfo memoryInfo = new ActivityManager.MemoryInfo();
    activityManager.getMemoryInfo(memoryInfo);

    return memoryInfo.lowMemory;
}
0
iMobaio