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

Bad*_*dal 103 android memory-management

我使用/ proc/meminfo和解析命令响应.但是它的结果显示:

MemTotal:94348 kB MemFree:5784 kB

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

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

Bad*_*dal 167

注意:此答案测量DEVICE的内存使用/可用.这不是您的应用程序可用的内容.要测量您的APP正在做什么,并且允许这样做,请使用android开发人员的答案.


Android文档 - ActivityManager.MemoryInfo

  1. parse/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;
    
    Run Code Online (Sandbox Code Playgroud)

数字0x100000L的说明

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

1024 * 1024     == 1048576
1048576         == 0x100000
Run Code Online (Sandbox Code Playgroud)

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

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

  • 转换为上面的两倍,否则percentAvail将为0 (2认同)
  • @Rolfツ抱歉,1024 字节等于 1 Kibibyte,1024 Kibibyte 等于 1 MibiByte。Kilo 和 Mega 是十进制前缀。1000 字节 = 1 千字节。这在答案中解释也是错误的。 (2认同)

and*_*per 76

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


通常,您想知道堆内存的状态,因为如果它使用太多内存,您将获得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;
Run Code Online (Sandbox Code Playgroud)

"usedMemInMB"变量越接近"maxHeapSizeInMB",越接近availHeapSizeInMB零,越接近OOM.(由于内存碎片,你可能会在达到零之前获得OOM.)

这也是内存使用的DDMS工具所显示的内容.


或者,有真正的RAM使用,这是整个系统使用多少 - 看到接受的答案来计算.


更新:因为Android O使您的应用程序也使用本机RAM(至少对于Bitmaps存储,这通常是大量内存使用的主要原因),而不仅仅是堆,事情已经改变,并且您获得更少的OOM(因为堆不再包含位图,请点击此处),但如果您怀疑内存泄漏,仍应密切关注内存使用情况.在Android O上,如果你有内存泄漏,应该在旧版本上引起OOM,它似乎只会崩溃而你无法捕获它.以下是检查内存使用情况的方法:

 val nativeHeapSize = Debug.getNativeHeapSize()
 val nativeHeapFreeSize = Debug.getNativeHeapFreeSize()
 val usedMemInBytes = nativeHeapSize - nativeHeapFreeSize
 val usedMemInPercentage = usedMemInBytes * 100 / nativeHeapSize
Run Code Online (Sandbox Code Playgroud)

但我相信最好使用IDE的分析器,它使用图表实时显示数据.

所以关于Android O的好消息是由于OOM存储过多的大位图而导致崩溃更加困难,但坏消息是我不认为在运行时可能会遇到这种情况.


Sha*_*lee 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;

}
Run Code Online (Sandbox Code Playgroud)

  • 这是一种简单的方法,但正如文档中所示,Runtime类的freeMemory()方法返回当前程序或应用程序的可用内存.所以在使用时要注意这一点. (4认同)
  • @Peter - 是的,它是"错误的",因为它回答了一个与问题不同的问题.另一方面,对于应用程序开发人员通常需要知道的内容,这是"正确的":DEVICE上的整体内存状态很少 - 如果用户运行了大量应用程序,OS*应该*使用大部分内存 - 否则效率低下.操作系统需要知道接受的答案给出了什么,知道何时开始杀死最近没有使用的应用程序.但是app程序员需要知道这个答案(和android开发人员的类似答案)告诉你的是什么,而不是runtime.maxMemory. (2认同)
  • 在许多设备(例如小米)上,`Runtime.freeMemory()`返回0,而`Runtime.totalMemory()`仅返回当前分配的内存。 (2认同)

yan*_*nko 17

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

MemoryInfo mi = new MemoryInfo();
ActivityManager activityManager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
activityManager.getMemoryInfo(mi);
long availableMegs = mi.availMem / 1048576L;
Run Code Online (Sandbox Code Playgroud)

  • 总是得到0.0 (4认同)

sar*_*old 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

+/-缓冲区/缓存:行是神奇的线,它报告说我真的有大约589兆的主动所需的进程内存,大约5391兆的"免费"内存,从91 + 374兆字节的意义上来说如果内存在其他地方可以更有利地使用,则可以丢弃缓冲区/缓存内存.

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

如果Android未附带free(1),您可以自己使用该/proc/meminfo文件进行数学运算; 我只是喜欢free(1)输出格式.:)


Hog*_*gun 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;
    }
Run Code Online (Sandbox Code Playgroud)

我知道Pattern.compile()是昂贵的成本,所以你可以将其代码移动到类成员.


归档时间:

查看次数:

181404 次

最近记录:

6 年,4 月 前