内存信息查看
Android手机的内存大小信息存放在手机系统的 /proc/meminfo
文件里面,我们可以通过读取这个文件来获取内存信息。
使用 cmd 命令行打开终端或直接在 Android Studio 中使用命令终端,运行 adb 命令可以看到文件详细内容如下所示:
C:\Users\YZJ>adb shell
sagit:/ $ cat /proc/meminfo
MemTotal: 5861796 kB
MemFree: 86060 kB
MemAvailable: 2236400 kB
Buffers: 83668 kB
Cached: 2069156 kB
SwapCached: 13432 kB
Active: 2440572 kB
Inactive: 1487968 kB
Active(anon): 1437024 kB
Inactive(anon): 471244 kB
Active(file): 1003548 kB
Inactive(file): 1016724 kB
Unevictable: 130564 kB
Mlocked: 130564 kB
SwapTotal: 2621436 kB
SwapFree: 1846508 kB
Dirty: 152 kB
Writeback: 0 kB
AnonPages: 1899920 kB
Mapped: 661984 kB
Shmem: 2520 kB
Slab: 408472 kB
SReclaimable: 161756 kB
SUnreclaim: 246716 kB
KernelStack: 70960 kB
PageTables: 95204 kB
NFS_Unstable: 0 kB
Bounce: 0 kB
WritebackTmp: 0 kB
CommitLimit: 5552332 kB
Committed_AS: 104783600 kB
VmallocTotal: 258867136 kB
VmallocUsed: 0 kB
VmallocChunk: 0 kB
CmaTotal: 163840 kB
CmaFree: 128 kB
下面介绍常见的几项:
(1)MemTotal: 所有可用RAM大小。(即物理内存减去一些预留位和内核的二进制代码大小)
(2)MemFree: LowFree与HighFree的总和,被系统留着未使用的内存。
(3)Buffers: 用来给文件做缓冲大小。
(4)Cached: 被高速缓冲存储器(cache memory)用的内存的大小(等于diskcache minus SwapCache)。
(5)SwapCached: 被高速缓冲存储器(cache memory)用的交换空间的大小。已经被交换出来的内存,仍然被存放在swapfile中,用来在需要的时候很快的被替换而不需要再次打开I/O端口。
(6)Active: 在活跃使用中的缓冲或高速缓冲存储器页面文件的大小,除非非常必要,否则不会被移作他用。
(7)Inactive: 在不经常使用中的缓冲或高速缓冲存储器页面文件的大小,可能被用于其他途径。
(8)SwapTotal: 交换空间的总大小。
(9)SwapFree: 未被使用交换空间的大小。
(10)Dirty: 等待被写回到磁盘的内存大小。
(11)Writeback: 正在被写回到磁盘的内存大小。
(12)AnonPages: 未映射页的内存大小。
(13)Mapped: 设备和文件等映射的大小。
(14)Slab: 内核数据结构缓存的大小,可以减少申请和释放内存带来的消耗。
(15)SReclaimable: 可收回Slab的大小。
(16)SUnreclaim: 不可收回Slab的大小(SUnreclaim+SReclaimable=Slab)。
(17)PageTables: 管理内存分页页面的索引表的大小。
(18)NFS_Unstable: 不稳定页表的大小。
获取内存信息方法
获取 android 当前可用运行内存大小
public static String getAvailMemory(Context context) {
ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
ActivityManager.MemoryInfo mi = new ActivityManager.MemoryInfo();
am.getMemoryInfo(mi);
// mi.availMem; 当前系统的可用内存
return Formatter.formatFileSize(context, mi.availMem);// 将获取的内存大小规格化
}
获取android总运行内存大小
public static String getTotalMemory(Context context) {
String str1 = "/proc/meminfo";// 系统内存信息文件
String str2;
String[] arrayOfString;
long initial_memory = 0;
try {
FileReader localFileReader = new FileReader(str1);
BufferedReader localBufferedReader = new BufferedReader(localFileReader, 8192);
str2 = localBufferedReader.readLine();// 读取meminfo第一行,系统总内存大小
arrayOfString = str2.split("\\s+");
for (String num : arrayOfString) {
Log.i(str2, num + "\t");
}
// 获得系统总内存,单位是KB
int i = Integer.valueOf(arrayOfString[1]).intValue();
//int值乘以1024转换为long类型
initial_memory = new Long((long)i*1024);
localBufferedReader.close();
} catch (IOException e) {
}
return Formatter.formatFileSize(context, initial_memory);// Byte转换为KB或者MB,内存大小规格化
}
实现内存分配的方法
内存分配的方法,使用ndk开发,引用realloc、malloc、calloc三个方法实现内存的分配。
ANSI C说明了三个用于存储空间动态分配的函数:
(1) malloc 分配指定字节数的存储区。此存储区中的初始值不确定 。
(2) calloc 为指定长度的对象,分配能容纳其指定个数的存储空间。该空间中的每一位(bit)都初始化为0 。
(3) realloc 更改以前分配区的长度(增加或减少)。当增加长度时,可能需将以前分配区的内容移到另一个足够大的区域,而新增区域内的初始值则不确定。
1、malloc
原型 : extern void *malloc(unsigned int num_bytes);
何时使用:当需要在内存的动态存储区中分配一块长度为num_bytes
字节的连续区域时。参数num_bytes
为需要的内存空间的长度,返回该区域的地址。
特点:
malloc在动态分配完内存后不对分配的内存空间初始化,里边数据是随机的垃圾数据。
实现原理:
它有一个将可用的内存块连接为一个长长的列表的所谓空闲链表。调用malloc函数时,它沿链表寻找一个大到足以满足用户请求所需要的内存 块。然后,将该内存块一分为二(一块的大小与用户请求的大小相等,另一块的大小就是剩下的字节)。接下来,将分配给用户的那块内存传给用户,并将剩下的那块(如果有的话)返回到连接表上。调用free
函数时,它将用户释放的内存块连接到空闲链上。到最后,空闲链会被切成很多的小内存片段,如果这时用户申请一个大的内存片段,那么空闲链上可能没有可以满足用户要求的片段了。于是,malloc
函数请求延时,并开始在空闲链上翻箱倒柜地检查各内存片段,对它们进行整理,将相邻的小空闲块合并成较大的内存块。如果无法获得符合要求的内存块,malloc
函数会返回NULL
指针,因此在调用malloc
动态申请内存块时,一定要进行返回值的判断。
2、calloc
原型:void *calloc(size_t n, size_t size);
何时使用:当需要在内存的动态存储区中分配n
个长度为size_t size
字节的连续空间时。如果分配成功,函数返回一个指向分配起始地址的指针;如果分配不成功,返回NULL
。
特点:
calloc在动态分配完内存后,自动初始化该内存空间为零。
3、realloc
原型:extern void *realloc(void *mem_address, unsigned int newsize);
何时使用:当需要在已经被(malloc(), calloc(),
或realloc()
)分配的空间的基础上重新分配空间时。参数mem_address
为原有的空间地址,newsize
是重新申请的地址空间。
特点:
- ①传递给
realloc
的指针必须是先前通过malloc(), calloc(),
或realloc()
分配的。 - ②如果
realloc
需要的内存小于原来的内存大小,会导致数据丢失;如果原来的内存后面还有足够多剩余内存的话,realloc的内存=原来的内存+剩余内存
,realloc
还是返回原来内存的地址;如果原来的内存后面没有足够多剩余内存的话,realloc
将申请新的内存,然后把原来的内存数据拷贝到新内存里,原来的内存将被free
掉,realloc
返回新内存的地址。 - ③如果没有足够可用的内存用来完成重新分配(扩大原来的内存块或者分配新的内存块),则返回
NULL
。而原来的内存块保持不变。 - ④如果
newsize
大小为0
,那么释放mem_address
指向的内存,并返回NULL
。 - ⑤如果
mem_address
为NULL
,则realloc()
和malloc()
类似。分配一个newsize
的内存块,返回一个指向该内存块的指针。