我已经使用了/ proc / meminfo并解析了命令response。但是结果表明:
内存总计:94348 kB内存空闲:5784 kB
手段。它显示只有5MB的可用内存。Android Mobile可能吗?我的手机上仅安装了5-6个应用程序,没有其他任务在运行。但是此命令仍然显示可用内存很少。
有人可以澄清吗?还是有任何其他方式来获取android中的内存使用情况?
我已经使用了/ proc / meminfo并解析了命令response。但是结果表明:
内存总计:94348 kB内存空闲:5784 kB
手段。它显示只有5MB的可用内存。Android Mobile可能吗?我的手机上仅安装了5-6个应用程序,没有其他任务在运行。但是此命令仍然显示可用内存很少。
有人可以澄清吗?还是有任何其他方式来获取android中的内存使用情况?
Answers:
注意:此答案用于衡量设备的内存使用情况/可用空间。这不是您的应用可用的功能。要衡量您的APP在做什么以及被允许做什么,请使用android开发人员的答案。
Android文档-ActivityManager.MemoryInfo
解析/ proc / meminfo命令。您可以在此处找到参考代码:获取Android中的内存使用情况
使用下面的代码并获取当前的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
很明显,该数字用于将字节转换为兆字节
PS:我们只需要计算一次总内存。因此,在代码中只调用一次点1,然后再调用一次,就可以重复调用点2的代码。
这取决于您对要获取的内存查询的定义。
通常,您想知道堆内存的状态,因为如果堆内存使用过多,则会出现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减少了(因为堆不再包含位图,请在此处检查),但是如果您怀疑内存泄漏,则仍应注意内存使用情况。在Android O上,如果您的内存泄漏本应在较旧版本上导致OOM,则似乎它会崩溃而无法捕获它。这是检查内存使用情况的方法:
val nativeHeapSize = Debug.getNativeHeapSize()
val nativeHeapFreeSize = Debug.getNativeHeapFreeSize()
val usedMemInBytes = nativeHeapSize - nativeHeapFreeSize
val usedMemInPercentage = usedMemInBytes * 100 / nativeHeapSize
但是我相信最好使用IDE的探查器,该探查器使用图形实时显示数据。
因此,Android O上的一个好消息是,由于OOM存储了太多的大位图而导致崩溃更加困难,但是坏消息是,我认为在运行时无法捕获这种情况。
编辑:似乎Debug.getNativeHeapSize()
随着时间的变化,因为它显示您的应用程序的总最大内存。因此,这些功能仅用于探查器,以显示您的应用程序正在使用多少。
如果要获取实际的总可用RAM,请使用以下命令:
val memoryInfo = ActivityManager.MemoryInfo()
(getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager).getMemoryInfo(memoryInfo)
val nativeHeapSize = memoryInfo.totalMem
val nativeHeapFreeSize = memoryInfo.availMem
val usedMemInBytes = nativeHeapSize - nativeHeapFreeSize
val usedMemInPercentage = usedMemInBytes * 100 / nativeHeapSize
Log.d("AppLog", "total:${Formatter.formatFileSize(this, nativeHeapSize)} " +
"free:${Formatter.formatFileSize(this, nativeHeapFreeSize)} " +
"used:${Formatter.formatFileSize(this, usedMemInBytes)} ($usedMemInPercentage%)")
这是一种计算当前正在运行的应用程序的内存使用量的方法:
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;
}
Runtime.freeMemory()
返回0并Runtime.totalMemory()
仅返回当前分配的内存。
另一种方式(当前在我的G1上显示25MB的可用空间):
MemoryInfo mi = new MemoryInfo();
ActivityManager activityManager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
activityManager.getMemoryInfo(mi);
long availableMegs = mi.availMem / 1048576L;
Linux的内存管理理念是“空闲内存就是浪费的内存”。
我假设接下来的两行将显示“缓冲区”中有多少内存,以及“缓存”中有多少内存。尽管两者之间有区别(请不要问那是什么区别:),它们两者的总和大约等于用于缓存文件数据和元数据的内存量。
该free(1)
命令是在Linux系统上释放内存的更有用的指南。在我的桌面上,它报告如下信息:
$ free -m 已使用的可用共享缓冲区总数 内存:5980 1055 4924 0 91374 -/ +缓冲区/缓存:589 5391 掉期:6347 0 6347
+/- buffers / cache:行是神奇的行,它报告说我确实有大约589兆的活动需要的进程内存和大约5391兆的“可用”内存,也就是说91 + 374兆字节如果可以在其他地方更有利地使用该内存,则可以丢弃一部分缓冲区/缓存的内存。
(我的机器已经运行了大约三个小时,除了stackoverflow几乎什么都不做,这就是为什么我有这么多可用内存的原因。)
如果Android不附带free(1)
,则您可以自己对该/proc/meminfo
文件进行数学计算;我只是喜欢free(1)
输出格式。:)
cat /proc/meminfo
代替。它要详细得多,但是MemFree
。Buffers
,并且Cached
可能是最重要的行。
我引用的著作很少。
参考:
此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()的成本很高,因此您可以将其代码移至类成员。
我看了看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中。
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;
}
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?
这是查看应用程序内存使用情况的另一种方法:
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
对于整体内存使用情况:
adb shell dumpsys meminfo
https://developer.android.com/studio/command-line/dumpsys#meminfo
Debug.getNativeHeapFreeSize()
。