1、GC机制
首先我觉得需要先说下虚拟机中的5个内存区域:方法区、堆、虚拟机栈、本地方法栈、程序计数器
在上面介绍的五个内存区域中,有3个是不需要进行垃圾回收的:本地方法栈、程序计数器、虚拟机栈。因为他们的生命周期是和线程同步的,随着线程的销毁,他们占用的内存会自动释放。所以,只有方法区和堆区需要进行垃圾回收,回收的对象就是那些不存在任何引用的对象。
而且方法区的垃圾回收效果很不理想,所以我们关注的垃圾回收的内存区域主要是堆。
判断一个对象是否可以被回收一般采用的算法是“可达性分析算法”,当一个对象到GC Roots没有任何引用链相连,这个对象就是可以被回收的,在java中可以作为GC Roots的对象有:
- 虚拟机栈(栈帧中的本地变量表)中引用的对象
- 方法区中类静态属性引用的变量
- 方法区中常量引用的对象
- 本地方法栈中JNI引用的对象
堆内存区域又分为新生代、老年代,新生代又分为一个一个Eden区,两个Survivor区,一般这两个区域大小比例是8:1(为什么是两个Survivor,主要是解决碎片化问题,https://blog.csdn.net/antony9118/article/details/51425581),每次使用Eden区和一块Survivor区,当回收时,将Eden和Survivor中还存活的对象一次性的复制到另一块Survivor空间上,最后清理掉Eden和刚才用过的Survivor,同时替换两个Survivor标记,如果另一块Survivor空间没有足够空间存放上一次新生代收集下来的存活对象时,这些对象将直接通过分配担保机制进入老年代。新生代采用的是“复制算法”收集内存,老年代采用的是“标记-整理“算法。
2、Activity的onNewIntent
经验证,这幅图完全正确
来源:http://baurine.github.io/2015/12/26/android_onnewintent.html
假设有两个Activity A和B,怎么验证A执行了onPause但是没有执行onStop,并且A还处于栈顶呢?很简单,设置B的启动模式为singleInstance
3、JVM、Dalvik、ART
Dalvik是基于寄存器的,而JVM是基于栈的。
Dalvik运行dex文件,而JVM运行java字节码
在Dalvik下,应用每次运行的时候,字节码都需要通过即时编译器(just in time ,JIT)转换为机器码,这会拖慢应用的运行效率,而在ART 环境中,应用在第一次安装的时候,字节码就会预先编译成机器码,使其成为真正的本地应用。这个过程叫做预编译(AOT,Ahead-Of-Time)。这样的话,应用的启动(首次)和执行都会变得更加快速。