- Java的一次编译到处运行背后:JVM从软件层面屏蔽了底层硬件、指令字节码的细节(JVM充当了适配器的角色和功能)
- JVM\JDK\JRE关系
2、JVM运行时数据区
所有学过的知识是用来推导新的未知的知识的,踏入社会要学会运用自己的知识能力去验证、求证自己的观点,这是必须具备的能力,过分依赖别人是危险的;用别人的长处来弥补自己的短处,借力提高。
线程时最小的执行单位,是一个执行者:
JDK1.6+Hotspot虚拟机:
- 程序计数器:指向当前线程正在执行的字节码指令的地址(行号),有点类似计算机底层的指令计数器
- 虚拟机栈:栈-》数据结构-》存储数据-》存储当前线程运行方法时所需要的数据、指令、返回地址;Java类中的方法是要被调用才能执行的,这个调用方式可以是常见的main方法,也可以是其他线程来调用。线程调用执行方法时需要从虚拟机栈中加载所需要的数据、指令、返回地址,这些就存储在虚拟栈中,并且一个方法对应一个栈帧;
- 本地方法栈:比如native方法,system.out.println();system.currentmillions()等
- 方法区:类信息(class文件)、常量(1.7+以后有变化:字符串常量切到堆里去了)、静态变量、JIT(1.7以前)-》永久代溢出
- Heap:注意永久代的颜色和方法区是一样的;新生代:Eden:survivor from:survivor to 比例为8:1:1,但是如果大对象分配内存失败,会通过老年代的担保机制直接进入老年代;
jvm参数设置:xms 初始化值 xmx (max)最大值,xmn(new)新生代大小;
垃圾回收:垃圾回收算法是理论,垃圾回收器是实践具体的垃圾回收算法的;
- 标记清除:产生内存碎片;
- 复制算法:内存按容量划分为大小相等两块,每次只使用其中一块。一块内存用完还存活着的对象复制另外一块,然后再把已使用的内存空间一次清理掉。消除了内存碎片现象,但是却对内存空间的使用做出了高昂的代价,因为能够使用的内存缩减到原来的一半;
- 标记整理:在完成标记之后,它不是直接清理可回收对象,而是将存活对象都向一端移动,然后清理掉端边界以外的内存;
- 分代回收算法:根据对象存活的生命周期将内存划分为若干个不同的区域。一般情况下将堆区划分为老年代(Tenured Generation)和新生代(Young Generation);大部分垃圾收集器对于新生代都采取复制算法,但是新生代的空间不是1:1划分的,而是按照8:1:1划分为Eden、survivor1,survivor2;老年代的特点是每次回收都只回收少量对象,一般使用的是标记-整理算法(压缩法)