背景
Android内存优化,首先需要了解Android其本身的存在方式与应用程序的进程运行。
(1)Android目前主流还是使用Java作为开发语言,当前还有谷歌推荐的Kotlin和Flutter等,我们所讨论的重点还是在于Java语言,传统的Java程序会把Java写的代码编译成class文件进行保存,而Android编译成的是一个APK文件,相当于一个压缩包,但是通过反编译和解压出来后我们可以发现有.dex文件, 程序小的可能只有一个dex文件,当时现在很多大型的Android程序都会把dex拆分成几个到几十个不等的dex文件。一个dex文件内部还有许多.class文件。
(2)JVM是基于栈结构,而Android虚拟机Dalvik基于寄存器,寄存器具有速度快等优点,谷歌在对Android进行了区别于JVM特定的优化,保证Android程序能流程的运行在手机上。
(3)每个Android应用程序都会运行在自己独立的Linux进程当中,Dalvik通过Zygote创建,Zygote会在系统启动时init得到,并且Zygote会创建一个Dalvik实例,每当一个应用程序启动时都会通过复制一个Dalvik实例进行分配内存yu与运行环境,每个Dalvik都是独立运行在自己密闭的空间里直到老去(系统回收)。
(4)每个Android应用程序都会分配到一个Linux的PID,并加以权限控制,这个权限等级关系到系统内存紧张时的内存回收策略。
(5)虽说Java是经过特定的内存资源分配和自动回收,区别于C/C++等需要手动进行置空或者手动free,但是Java本身对kai开发者使用时的不规范性没ji进行约束,会导致使用内存时也会存在不当,导致内存得不到回收或者久久不能释放,使得Android系统变得异常卡顿。
查看内存使用的手段
想查看具体某一个Android进行的内存与CPU使用情况,首先需要了解一下具体内存缩写表示:
VSS:Virtual Set Size,表示虚拟使用的内存(包含共享库占用的内存);
RSS:Resident Set Size,表示实际使用的物理内存(包含共享库占用的内存);
PSS:Proportional Set Size,表示实际使用的物理内存(比例分配共享库占用的内存);
USS:Unique Set SizeSize,表示进行独占的物理内存(不包含共享库占用的内存);
一般来说VSS>=RSS>=PSS>=USS
查看内存的具体有四种方法。
(1)通过Android提供的API方法进行查看
ActivityManager.MemoryInfo info = new ActivityManager.Memory.info();
ActivityManager mActivityManager = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE);
mActivityManager.getMemoryInfo(info);
getMemoryInfo表示可用的空闲内存。
(2)通过Linux的/proc文件系统的meminfo文件分析
在系统文件目录下/proc/meminfo记录着系统内存使用的情况。
MemTotal:xxx kb
MemFree:xxx kb
Buffers: xxx kb
Cachee:xxx kb
空闲内存 = free+buffers+cached = total - used
(3)通过runtime类(执行adb命令)
Android提供Runtime类可直接adb命令,从而实现查询内存的功能,dada当然也可以直接通过cmd控制台运行adb命令进行内存信息的打印。
final Process process = Runtime.getRuntime().exec("/system/bin/top -n 10")
或者直接使用adb命令 adb shell dumpsys meminfo <package_name>
其中,package_name 也可以换成程序的pid,pid可以通过 adb shell top | grep app_name 来查找;
(4)通过DDMS工具获取内存信息
作为一名Android开发,都会接触到DDMS的使用,DDMS全称Dalvik Debug Monitor Service,从全称来看该工具很明显是让我们更好更方便的调试Dalvik虚拟机。
其中我们可以启动eclipse或者Android studio打开DDMS,使用Heap进行检测进程内存信息,通过选择我们的Devices视图的“Update Heap”来更新信息,点击“Cause GC”进行内存回收,通过多次对比观察内存数据变化,得到内存的使用情况。