工具集:dexdump(反编译dex)、dexdeps(依赖)、dexlist(列出类和方法)、dexopt(->Odex)、dvz()、Heap Profile、
Zygote线程管理:每个App都运行在一个Dalvik实例中,每个实例都是一个独立进程空间。Zygote进程是系统启动时产生,它会完成虚拟机的初始化、库的加载,预置类库的加载和初始化。通过复制自身快速提供一个虚拟机示例。 对一些只读系统库,所有虚拟机实例都和Zygote共享一块内存区域。
类加载:解析Dex文件并加载Dalvik字节码(存入该类的运行时数据结构,供解释器执行)。加载类分为基础类库和用户自定义 类,当虚拟机装载某类时,类加载器定位字节码文件,读入数据信息并存储到对应内存。Android系统启动时会加载所有基础类库,用户自定义类库是在虚拟机运行时载入。
内存管理:分配系统启动初始化和应用程序运行时需要的内存资源。dlmalloc内存分配器,Mark-Sweep回收。
JNI:
反射机制:
解释器:根据自身的指令集Dalvik ByteCode解释字节码(两种:移植型和快速型。分别基于C和汇编,入口interp.cpp中dvmInterpret决定使用哪种)。[解释指逐句翻译执行,编译指先翻译整个程序再执行]
即时编译:将反复执行的热代码编译成本地码,降低解释器压力。同时包含解释和编译重复方法。
Dalvik基于ARM(RISC的CPU,具有丰富的寄存器)。避免了过多的访存指令。
1、Dex文件及Dalvik字节码格式解析:【基础数据结构、字节码指令】[Dex文件结构、Dex文件头部、内部数据索引、Dex文件数据区]
当一个真实设备在执行目标dex文件前需要优化dex文件生成Odex(本质仍然是dex,字节码验证,替换优化及空方法消除)
2、Odex:安全性校验及平台性优化,[Odex文件结构、Odex文件头部、原Dex文件,依赖库信息,辅助信息]长期保留目标程序的优化数据。
Memory Analyse:
1、tracing view:WRITE_EXTERNAL_STORAGE、MOUNT_UNMOUT_FILESYSTEMS
代码块:Android.os.Debug.startMethodTracing("/sdcard/test");关闭方法stopMethodTracing();
命令:traceview PCPath
2、Heap Profile:
代码块:try{ Android.os.Debug.dumpHprofData("/data/tmp/input.hprof"); }catch(IOException e){}
使用hprof-conv工具将hprof文件转换成标准格式(hprof-conv input.hprof out.hprof)[input.hprof为非标准文件,直接展示报错]
配置MAT查看out.hprof;
Dalvik各部分功能:线程管理、类加载、解释器、内存管理、即时编译、本地方法调用、反射机制、调试支撑。
x86入口:Main.c :main(); ARM:AndroidRuntime.startVm();
JNI_CreateJavaVM():①检查JNI版本是否正确;②解析命令行参数,初始化JNIEnv和JavaVM全局变量;③初始化全局变量gDvm;④调用dvmStartup初始化虚拟机的各个模块,包括初始化垃圾收集器、类加载器、字节码校验模块和解释器等,完成各模块的初始化后创建一个线程;⑤装载Dalvik虚拟机运行时核心类库并校验字节码;
Zygote先孵化system_server进程(会监听socket),复制自身共享资源(Android Framework)。
Zygote工作流程:
(1)init进程通过app_process开启Zygote进程;
(2)app_process生成AppRuntime对象,分析其主函数传递的参数,并start();start():
①startVM,注册虚拟机;②startReg,注册JNI;③运行ZygoteInit::main;
(3)ZygoteInit是Zygote的main函数入口,是Zygote的核心类,完成Zygote的职责:
①registerZygoteSocket创建socket接口,绑定socket套接字,接受AndroidApp运行请求;
②preloadClass和preloadResource加载Framework使用的类和资源;
③startSystemServer->forkSystemServer()分裂出“system_server”进程,并启动各项系统服务,最终加入到Binder通信系统;
④runSelectLoopMode进入一个无限循环,监听socket。接受到连接对象ZygoteConnection(连接管理及参数解析),runOnce运行App。runOnce():读取system_server发送过来的参数,调用Dalvik虚拟机中的forkAndSpecialize()创建子进程(支持Zygote?堆?信号机制?日志?子进程?)。复制:task_struct、系统堆栈空间和页面表,改变:COW技术
fork返回三个pid,在子进程返回0,在父进程中返回新创建子进程的进程ID。
Dalvik运行主要流程:
类加载:①取得Dex原始文件,并将其还原到内存,并关联DexFile结构体对象;②对Dex中各个类依次加载生成类对象实例,并将对象指针交付解释器引用执行;