1,JVM是什么 Java中的JDK中包含运行的工具Tools,ToolApis,JRE,JRE移除libs和开发环境那些就是JVM,JVM实际上就是将class文件(字节码文件)翻译成机器可以识别的机器码(二级制文件)的中间工具,JRE可以理解位Java运行时的环境,还包含各种类库,JVM的特点一次编译,多次运行,所以也可以解释它的跨平台性。
2,JVM的运行时数据区
一个class文件通过JVM中的类加载器(class loader)加载到运行时数据区中,也可以理解成加载到内存中,运行时数据区有分为方法区,堆,Java栈,本地方法栈和程序计数器,方法区和堆是所有线程共享的,Java栈,本地方法区和程序计数器是线程私有的,不管创建多少个线程,方法区和堆只有一个,私有的和线程数一致.
3,线程私有的虚拟机栈 虚拟机栈:存储当前和运行方法所需的指令,数据,返回地址
栈帧:类中每个方法对应一个栈帧
栈帧还可以划分为:局部变量表,操作数栈,动态链接,返回地址
线程私有的其他
本地方法栈:储存当前线程运行的Native方法所需的数据,指令,返回地址
程序计数器:当前线程正在执行的字节码指令的地址(行号)
4,线程共享
线程共享中包含方法区和堆,方法区中一般存储常量和静态变量,字节码,方法区中存储的内容可以长期存储,方法区和堆的生命周期不是跟随线程的,和分代,垃圾回收GC有关。
5,JVM的内存模型 线程私有,共享
堆:新生代(Eden空间,交换区(From Survivor空间,To Survivor空间))可选用复制算法回收;老年代必须使用标记清楚或标记整理算法回收
方法区:永久代(JDK < 1.8); 元空间(JDK >= 1.8)对象不能被回收
新new的对象一般在Eden区,如果对象占用内存大于Eden区内存大小,会直接晋级到老年代
Eden区如果满了,会进行垃圾回收,垃圾回收时会根据响应算法计算(可达性分析算法)
可达性分析算法:GCRoot(对象(常量,静态变量,虚拟机栈中局部变量表里面正在引用的对象,本地方法栈中引用的局部变量表中的对象)),判断对象是否和GCRoot有引用即可达,不会被GC回收,没有被GC回收的对象会从Eden区转移到交换区就会有个年龄的增加,一般情况下经过15次后,对象会被存放到老年代。
Android中内存回收机制
1,对象创建后在Eden区
2,执行GC后,如果对象仍然存储,则复制到SO区
3,当SO区满时,该区域存活对象将复制到S1区,然后SO清空,接下来SO和S1角色互换
4,当第三步达到一定次数(系统版本不同会有差异,一般是15次)后,存活对象将被复制到Old Generation
5,当这个对象在Old Generation区域停留的时间达到一定程度时,它会被移动到Old Generation。最后累积一定时间再移动到Permanent Generation区域
Minor GC:回收区域:新生代;回收算法:复制回收算法
Full GC:回收区域:新生代,老年代,永久代;回收算法:老年代(标记清除算法,标记整理算法)
垃圾回收算法:复制回收算法,标记清除算法,标记整理算法
复制回收算法:优点:简单高效,不会出现内存碎片;缺点:内存利用率低,只能用一半内存,存活对象较多时,效率很低,Eden:From:To = 8:1:1
标记清除算法:优点:利用率百分之百,效率比较高;缺点:标记和清除的效率都不高(对比复制回收算法),会产生大量的内存碎片
标记整理算法:优点:利用率100%,不会产生内存碎片;缺点:标记和整理的效率都不高,效率对比与标记-清楚比较低
Full GC也是一个线程执行,垃圾收集线程执行占据了JVM 98%的资源,回收效率0 < 2%,就回抛出一个异常:** Exception in thread thread_name: java.lang.OutOfMemoryError: GC Overhead limit exceeded**
7,Android中低内存杀进程机制
从上至下依次是:Foreground Processes(前台进程)、Visible Processes(可见进程)、Service Processes(服务进程)、Background Processes(后台进程)、Empty Processes(空进程),越大越容易被回收