jvm的发展:
HotSpot VM(sun公司)以前使用最广泛的 ,边编译边运行,热点数据/多次运行的会翻译成二进制保存本地。
JRocket(bea)号称最快的jvm ,启动后把字节码文件编译成二进制文件,运行,运行速度快,但是启动慢
J9 VM(IBM)
Oracle 收购这两家,发布新版本,目前HotSpot是使用最广泛的Jvm.
jvm的作用:
内存分配和垃圾回收
jvm 内存模型:
包括: 堆 方法区 虚拟机栈 本地方法栈 程序计数器等
1.堆 大部分new出来的对象/反射 等都是放在该区域。堆中内存进一步分为 新生代(新生代包括了eden区和 survival(from)/survival(to))和老年代;
eden区域和两个survival区默认比值为8:1:1,因为java中只有小部分对象能够存活,比例小于2%或10%,
2 方法区,在jdk 1.7以前称为永久代,是在堆中分配空间,jdk1.8以后成为元空间,最大区别就是,元空间大小受限制与内 存 大小。方法区保存 类信息 常量 静态变量 JIT即时编译器编译后的代码等
这两部分是线程共享区域
3 程序计数器 ,jvm中唯一不会发生OOM,指向当前线程的指令位置或者class行号。因为java天生多线程,涉及到线程切 换,为了确保多线程环境下程序正常执行。
4虚拟机栈 ,有栈的特点,FILO先进后出,存放当前线程的数据/指令/返回地址。默认-Xss1M .
每个方法在使用时候创建栈帧,每个栈帧中包括了
a 局部变量表,存放8大基本数据类型和reference引用
b 操作数栈 对方法的调用,出栈入栈
c 动态链接 方法的多态
d 返回地址 方法返回地址
5 本地方法栈 保存的native方法,在调用本地方法时候,不会创建栈帧,在动态链接中直接调用。程序计数器也不保存行号
HotSpot把本地方法栈和虚拟机栈合二为一,其中在jvm中3.4.5三个是线程私有的,随着线程产生和销毁。
GC
gc主要针对堆中来讲,其中包括了垃圾回收算法
1. 复制算法,使用在新生代中,当eden区内存不够时候或者空间分配担保,会发起mirror GC。存活对象进入survival区域,在 from 和 to两个区域来回复制。速度快,内存空间连续,但是空间利用率低。新生代中的对象90%是朝生夕死,所以只有10%存活下来。
2 标记清除算法 产生空间随便,速度相对1要低。
3 标记整理算法 速度比2低
垃圾回收器:
单线程 | d多线程 | t特点 | |
新生代 | serial | par new parallel scavenge | G1 |
老年代 | serial old | cms parallel old |
新生代 | serial | 复制算法 | 单线程 |
par new
parallel scavenge | 复制算法 | 并行多线程收集器 | |
老年代 | serial old | 标记整理 | 单线程 |
cms | 标记清除 | 并发和并行收集器 | |
paralle old | 标记整理 | 并行多线程收集器 | |
G1 跨越新生代和老年代 | 化整为零 标记整理 | 并行和并发收集器 |
cms垃圾回收器:占用cpu资源,浮动垃圾/内存碎片
1 初始标记 用户线程暂停,时间短,主要为了查找gcRoots
2并发标记 用户线程和GC线程同时运行,时间长
3重新标记 用户线程暂停,时间短
4并发清理 用户线程和gc线程同时运行,时间长
G1 垃圾回收器:空间整合,不会产生垃圾碎片。可预测的停顿
gc模式:yong gc mixed gc
1.初始标记 主要为了查找gcRoots
2并发表及
3最终标记
4 回收
垃圾回收的对象:
1.引用计数法
2可达性分析 gcRoots
在Java, 可作为GC Roots的对象包括:
1.方法区中类静态属性引用的对象。
2.方法区中常量引用的对象。
3.虚拟机栈(本地变量表)中引用的对象。
本地方法栈JNI(Native方法)中引用的对象