JVM内存区域划分
- 线程栈
- 本地方法栈
- PC计数器
- 堆区 线程公用,对象一般都是分配在堆上
- 方法区 也属于堆的一部分里面存放了Class对象的元数据,比如符号引用,常量池等,jdk1.8方法区的实现是元空间,1.8之前是永久代。
- 堆外空间,由于JVM是也一个进程,所以JVM的内存空间大小=堆内大小+堆外大小
垃圾回收算法
标记清除
流程:把GCroot把不可达对象全部标记一遍,然后清除掉。
优点:实现简单高效
缺点:容易出现内存碎片
标记整理
流程:是对于标记清除算法的一个优化,清除完对象后会暂停工作线程,然后进行一个对象的整理
优点:没有内存碎片
缺点:会有stopTheWorld,影响其他工作线程
copy复制算法
流程:把内存2为个区域,一个used和一个free,对象是分配在used空间,然后扫描的时候也是used,把存活对象移动free。然后直接清空used空间,最后交互used和free的指针
优点:没有内存碎片,对象整理的时间也较短
缺点:空间利用率不高
JVM并没有直接使用上述的算法,而是把内存分为2个空间一个叫老年代一个新生代。对象几乎都是再新生代分配的,然后会把一些大对象或者长时间存活的对象移动到老年代。
新生代:yong区采用一个优化后的复制算法,把yong区划分为8:1:1(eden区:useed:free),每次对used和eden区进行标记,然后把存活的对象移动到free区,清空eden和used区域,交互used和free2个指针
老年代:由于老年代的对象都是存活时间比较久的,老年代就采用标记整理法。
晋升机制
- 每个对象头部的markword有一个age字段,每次进行GC都会age+1,当age超过阈值后晋升为老年代。
- 大对象直接分配老年代
- 动态年龄判断,如果某个年龄的对象综合超过used的区域一半,则年龄>=改年龄的对象直接晋升
CMS垃圾收集器
- 初始化标记
- 并发标记
- 补偿标记
- 并发清除2 CMS采用的是标记清除算法,如果浮动垃圾太多导致回收失败,会使用serialOld进行收集
G1收集器
G1收集器的特点是并发收集和回收时间可预测。
Class对象加载过程
- 加载,把类以二进制的方式加载进来
- 校验,判断该CLASS是否安全或者正确
- 准备,class的字段赋默认值
- 解析,把方法的符号引用转换为直接引用
- clInit,执行class的Init方法,就是执行静态代码块并且给静态字段赋值
类加载器
- 启动类加载器,负责javaHome\lib包
- 扩展类加载器,负责javaHome\lib\ext包
- 系统类加载器,负责classPath下的jar包记载
- 自定义加载器
一个方法的调用过程
静态调用:就是普通方法调用,方法的地址编译的时候就确定了,直接创建栈幁,把参数放入到局部变量表中把栈幁压入栈
动态调用:就是我的重写,调用的时候根据引用找到实际的对象,根据方法签名遍历对象的方法表,如果找到的,那么就进行一个权限校验。通过就返回,反之报错,如果对象本身方法表找不到就找父类。
栈幁
- 局部变量表
- 操作数栈
- 方法返回地址
JIT编译器
JIT是采用分层编译,优先解释执行,然后判断代码是否是热点代码,如果是的话则进行一个代码的编译,来加开代码的执行。
解释执行优点:不需要编译时间但是执行比慢
编译执行优点:编译时间和代码的膨胀,但是执行较快