如何在Android中获取当前的内存使用量?

时间:2010-07-03 07:28:56

标签: android memory-management

我使用了/ proc / meminfo并解析了命令响应。但是结果显示:

MemTotal:94348 kB MemFree:5784 kB

装置。它显示只有5MB的可用内存。 Android手机有可能吗? 我的手机上只安装了5-6个应用程序,没有其他任务正在运行。但是这个命令仍显示可用内存很少。

有人可以澄清一下吗?或者在android中有没有其他方法可以获取内存?

11 个答案:

答案 0 :(得分:158)

注意:此答案测量DEVICE的内存使用量/可用内容。这不是您的应用程序可用的内容。要衡量您的APP正在做什么,并且被允许这样做,Use android developer's answer


Android docs - ActivityManager.MemoryInfo

  1. 解析/ proc / meminfo命令。您可以在此处找到参考代码:Get Memory Usage in 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;
    
  3. 数字0x100000L的说明

    1024 bytes      == 1 Kibibyte 
    1024 Kibibyte   == 1 Mebibyte
    
    1024 * 1024     == 1048576
    1048576         == 0x100000
    

    很明显,这个数字用于从字节转换为mebibyte

    P.S:我们只需计算一次总内存。所以在你的代码中只调用一次点1然后再重复调用第2点的代码。

答案 1 :(得分:67)

这取决于您对要获取的内存查询的定义。


通常,您想知道堆内存的状态,因为如果它使用太多内存,您将获得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使用率,即整个系统使用的数量 - 请参阅accepted answer来计算。


更新:由于Android O使你的应用程序也使用本机RAM(至少对于Bitmaps存储,这通常是大量内存使用的主要原因),而不仅仅是堆,事情已经改变,你得到更少的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存储太多大位图而导致崩溃更加困难,但坏消息是我不认为在运行时可能会遇到这种情况。

答案 2 :(得分:28)

以下是计算当前正在运行的应用程序的内存使用量的方法

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;

}

答案 3 :(得分:17)

另一种方式(目前在我的G1上显示25MB免费):

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

答案 4 :(得分:12)

Linux的内存管理理念是“可用内存浪费内存”。

我假设接下来的两行将显示“缓冲区”中有多少内存,以及“缓存”多少。虽然两者之间存在差异(请不要问这有什么区别:)但它们大致相当于用于缓存文件数据和元数据的内存量。

Linux系统上可用内存的更有用指南是free(1)命令;在我的桌面上,它会报告如下信息:

$ free -m
             total       used       free     shared    buffers     cached
Mem:          5980       1055       4924          0         91        374
-/+ buffers/cache:        589       5391
Swap:         6347          0       6347

+/- buffers / cache:line是神奇的线,它报告说我确实得到了大约589 megs的主动所需进程内存,以及大约5391 megs的'free'内存,在91的意义上如果内存在其他地方可以更有利地使用,则可以丢弃+374兆字节的缓冲区/缓存内存。

(我的机器已经运行了大约三个小时,除了stackoverflow之外什么都没做,这就是我有这么多空闲内存的原因。)

如果Android未附带free(1),您可以使用/proc/meminfo文件自行完成数学计算。我只喜欢free(1)输出格式。 :)

答案 5 :(得分:6)

我参考了几篇文章。

<强>参考:

返回此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 :(得分:3)

我查看了Android Source Tree。

在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中。

备注

总计内存在API级别16中添加。

答案 7 :(得分:1)

你也可以使用DDMS工具,它是android SDK的一部分。 它也有助于获取java代码和本机c / c ++代码的内存分配。

答案 8 :(得分:0)

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;
}

答案 9 :(得分:0)

b.HasIndex("StudentId");

这是一个奇怪的代码。它返回MaxMemory-(totalMemory-freeMemory)。如果freeMemory等于0,则代码将返回MaxMemory-totalMemory,因此它可以大于或等于0。为什么不使用freeMemory?

答案 10 :(得分:0)

这是查看应用程序内存使用情况的另一种方法:

function equiv(index){
      return Array.prototype.slice.call( document.querySelectorAll("*"))[index];
}

function swap (val,val2){
    let _key = val.key;
    let _key_ = val2.key;
    _key_ = _key < _key_ ? _key_+1:_key_;
    let _parent_ = val2.parentElement.valueOf();
    if (val.parentElement.children.length ==1)
        val.parentElement.appendChild(val2);
    else
        val.parentElement.insertBefore(val2,val);
    if (_parent_.children.length ==0)
        _parent_.appendChild(val);
    else{
        let _sibling_ = equiv(_key_);
        _parent_.insertBefore(val,_sibling_);}
}

样本输出:

adb shell dumpsys meminfo <com.package.name> -d

有关整体内存使用情况:

Applications Memory Usage (kB):
Uptime: 2896577 Realtime: 2896577

** MEMINFO in pid 2094 [com.package.name] **
                   Pss  Private  Private  Swapped     Heap     Heap     Heap
                 Total    Dirty    Clean    Dirty     Size    Alloc     Free
                ------   ------   ------   ------   ------   ------   ------
  Native Heap     3472     3444        0        0     5348     4605      102
  Dalvik Heap     2349     2188        0        0     4640     4486      154
 Dalvik Other     1560     1392        0        0
        Stack      772      772        0        0
    Other dev        4        0        4        0
     .so mmap     2749     1040     1220        0
    .jar mmap        1        0        0        0
    .apk mmap      218        0       32        0
    .ttf mmap       38        0        4        0
    .dex mmap     3161       80     2564        0
   Other mmap        9        4        0        0
      Unknown       76       76        0        0
        TOTAL    14409     8996     3824        0     9988     9091      256

 Objects
               Views:       30         ViewRootImpl:        2
         AppContexts:        4           Activities:        2
              Assets:        2        AssetManagers:        2
       Local Binders:       17        Proxy Binders:       21
    Death Recipients:        7
     OpenSSL Sockets:        0

 SQL
         MEMORY_USED:        0
  PAGECACHE_OVERFLOW:        0          MALLOC_SIZE:        0

https://developer.android.com/studio/command-line/dumpsys#meminfo