AndroidAPK内存优化删减
来源:互联网 发布:淘宝助理打印设置 编辑:程序博客网 时间:2024/05/01 23:49
AndroidAPK内存优化删减
1、使用场景(内存)
1)APK启动应用时内存占用及分布,即初始化时(如内核初始化,外围资源加载等)各占多少
2)使用APK核心功能时内存占用及分布,如UI加载,数据加载保存
3)用户常用操作时内存占用及分布
2、通过命令查看内存占用及分布
1)命令:adbshell dumpsys meminfo yourpakagename
终端输入命令后,可以看到类似下图的结果
改命令实际的调用代码入口在android.os.Debug.java和对应的CPP文件android_os_Debug.cpp,Debug.java的getMeminfo方法实际上调用了android_os_Debug.cpp的android_os_Debug_getDirtyPagesPid方法。
static voidandroid_os_Debug_getDirtyPagesPid(JNIEnv *env, jobject clazz, jintpid, jobject object){stats_tstats[_NUM_HEAP];memset(&stats,0, sizeof(stats));load_maps(pid,stats);structgraphics_memory_pss graphics_mem;if(read_memtrack_memory(pid, &graphics_mem) == 0) {...}...}static voidload_maps(int pid, stats_t* stats){chartmp[128];FILE *fp;sprintf(tmp,"/proc/%d/smaps", pid);fp =fopen(tmp, "r");if (fp ==0) return;read_mapinfo(fp,stats);fclose(fp);}
从上面的代码可以看到,android_os_Debug_getDirtyPagesPid方法先调用了load_maps方法,而load_maps方法要做的事情也很简单,它打开/proc/PID/smaps虚拟文件,读取里面的信息,在已ROOT的设备上,我们可以通过“adbshell cat /proce/PID/smaps”直接将这个虚拟文件的信息打印在控制台上。
“adb shell cat/proce/PID/smaps”输出的信息实际上是应用的userspace地址空间的内存分配表,记录了应用分配的每一块内存的地址,类别,大小等信息,而load_maps方法调用read_mapinfo方法从这个表里面读出每一块内存的分配信息,分类进行累加,得出Native Heap,DalvikHeap等各个类别的内存占用。
更多具体讲解可以参考:http://tech.uc.cn/?p=2714
我们可以使用脚本对smaps解析得到更简化的内存数据分布。
2)命令:adbshell procrank
通过该命令可以获取所有进程的内存占用:
在linux下表示内存的耗用情况有四种不同的表现形式:
VSS- Virtual Set Size 虚拟耗用内存(包含共享库占用的内存)
RSS- Resident Set Size 实际使用物理内存(包含共享库占用的内存)
PSS- Proportional Set Size 实际使用的物理内存(比例分配共享库占用的内存)
USS- Unique Set Size 进程独自占用的物理内存(不包含共享库占用的内存)VSS:VSS表示一个进程可访问的全部内存地址空间的大小。这个大小包括了进程已经申请但尚未使用的内存空间。在实际中很少用这种方式来表示进程占用内存的情况,用它来表示单个进程的内存使用情况是不准确的。
RSS:表示一个进程在RAM中实际使用的空间地址大小,包括了全部共享库占用的内存,这种表示进程占用内存的情况也是不准确的。
PSS:表示一个进程在RAM中实际使用的空间地址大小,它按比例包含了共享库占用的内存。假如有3个进程使用同一个共享库,那么每个进程的PSS就包括了1/3大小的共享库内存。这种方式表示进程的内存使用情况较准确,但当只有一个进程使用共享库时,其情况和RSS一模一样。
USS:表示一个进程本身占用的内存空间大小,不包含其它任何成分,这是表示进程内存大小的最好方式!
可以看到:VSS>=RSS>=PSS>=USS
Note:这里有一个问题需要注意,如果一个APK里面只使用了32位的so库文件,在64位的机器上运行,一般系统系统会兼容。但是对应的PSS内存可能会比使用64位的so所占用的内存大。因为在32位共享库占用的内存可能会全部算到该APK的PSS内存里面(因为没有其他32位APK按比例分配共享库内存)
3、通过代码查看内存占用及分布
下面列举几种获取不同内存的方式:
publicstaticlongusedMemory() {finalRuntime s_runtime = Runtime.getRuntime();return(s_runtime.totalMemory() - s_runtime.freeMemory());}publicstaticintgetPssMemory(Context context) {finalActivityManager am = (ActivityManager) context.getSystemService(Activity.ACTIVITY_SERVICE);android.os.Debug.MemoryInfo[]memoryInfoArray = am.getProcessMemoryInfo(newint[]{android.os.Process.myPid()});returnmemoryInfoArray[0].getTotalPss();}/***Gets the total available memory (KB) on the system.*/publicstaticlonggetTotalAvailableMemory(Context context) {try{finalActivityManager am = (ActivityManager) context.getSystemService(Activity.ACTIVITY_SERVICE);ActivityManager.MemoryInfooutInfo = newActivityManager.MemoryInfo();am.getMemoryInfo(outInfo);return(long)outInfo.availMem/1024;}catch(Exceptione){return-1;}}/***Gets the total memory (KB) on the system.*/publicstaticlonggetTotalMemory(Context context) {try{finalActivityManager am = (ActivityManager) context.getSystemService(Activity.ACTIVITY_SERVICE);ActivityManager.MemoryInfooutInfo = newActivityManager.MemoryInfo();am.getMemoryInfo(outInfo);if(SystemPropertiesReflect.getSdkVersion()>= SystemPropertiesReflect.VERSION_CODES.JELLY_BEAN)return(long)outInfo.totalMem/1024;elsereturn-1;}catch(Exceptione){return-1;}}
4、删减内存常见方法
1)删减无用代码及功能资源
2)dex拆分(multidex)/插件话/动态加载
3)使用外部进程(android:process)
4)跑proguard,去掉无用的代码
5)缩减所使用的库的大小
6)尽量减少依赖的包
7)java代码优化
8)其他
- AndroidAPK内存优化删减
- Androidapk 反编译
- Androidapk美化
- Androidapk瘦身
- AndroidAPK瘦身
- 删减 ubuntu
- androidapk安装过程详解
- Mac下反编译AndroidAPK
- androidapk安装过程详解
- AndroidAPK二次打包方法
- 内存优化
- 内存优化
- 内存优化
- 内存优化
- 内存优化
- 内存优化
- 内存优化
- 内存优化
- Oracle 11G EXP 导出空表
- Uiautomator
- String ==和equals
- 使用JS控制伪元素的几种方法
- Android Cursor
- AndroidAPK内存优化删减
- 域控安装
- Android 7.0
- 卡尔曼滤波的学习应用
- Boolan* C++课程第五周笔记
- 程序猿学习第二天,列表和表格
- POJ 3237Tree(树链剖分-线段树点更新-区间更新-区间最值查询-入边)
- 题目1061:成绩排序
- 富文本编辑器防xss攻击