执行引擎(execution engine):执行classloader中的方法指令
-
解释器Interpreter:读取源码或字节码,并逐条直接执行(javac是在JVM外的)
-
即时编译器Just-In-Time compiler/JIT: 读取源码,更多情况下是字节码,然后即时编译为机器码并执行
-
Java虚拟机是可运行Java代码的假想计算机,java源文件(.java)通过java编译器javac生成字节码文件(.class),字节码文件(.class)通过JVM中的解释器再翻译成特定机器上的机器码
即,源码/源代码/Source code/.java -> 字节码/Bytecode/.class -> 机器码/Machine code/原生码/Native Code
类装载子系统(classloader sub-system):定位和导入二进制class文件,校验导入类的正确性,为类变量分配并初始化内存,解析符号引用
-
启动类加载器bootstrap classloader,负责加载JAVA_HOME/lib下的合法类文件
-
扩展类加载器extension classloader,负责加载JAVA_HOME/lib/ext下的合法类文件
-
应用程序类加载器application classloader,负责加载用户路径classpath下的合法类文件
-
自定义类加载器user defined classloader,class MyClassLoader extends ClassLoader
-
JVM通过双亲委派模型进行类的加载,先交给其最底层父类去加载,父类无法加载时才自己试着去加载。if(parent != null) parent.loadclass(name) 递归recursion,application classloader -> extension classloader -> bootstrap classloader
-
先看user defined classloader是否缓存了,如果缓存了,就直接返回,如果没有,委派父classloader去加载,如果父缓存了,就直接返回,否则再委派给父classloader;直到最后的bootstrap classloader,如果其缓存找不到,则在其路径下找,找到则至二级返回,否则往其子类返回,让其子类在其路径下找;最后又回到自定义classloader,如果还找不到就抛异常
可用内存缩小为原来的一半
每次收集时,所有的标记对象都要被拷贝,从而导致一些生命周期很长的对象被来回拷贝多次,消耗大量的时间 ->分代回收来解决这个问题
分代回收算法Generational Collecting:根据对象存活周期的不同将内存划分为几块新生代:内存分为一块较大的Eden空间和两块较小的Survivor空间。新建object在Eden,Eden满时触发YGC,Eden中存活对象被移动到S0区,清空Eden;等Eden再满载YGC,Eden和S0中的存活对象被复制到S1(复制算法保证了S1中来自Eden和S0两部分的存活对象占用连续的内存空间,避免了碎片化);清空Eden和S0。下一轮的时候S0和S1交换角色,如此循环往复。如果对象的复制次数达到15次,该对象就会被送到老年代。老年代:对象存活率高
垃圾回收器(垃圾回收算法的具体实现)
并行与并发
-
并行Parallel:指多条垃圾收集线程并行工作,但此时用户线程仍然处于等待状态
-
并发Concurrent:指用户线程与垃圾收集线程同时执行,用户程序在继续运行,而垃圾收集程序运行于另一个CPU上
-
新生代minor gc:新生代内存不是很大,miinor gc回收速度一般比较快
-
老年代major gc/ full gc:老年代内存一般比较大,用于缓存大对象,所以回收速度约minor gc的10倍以上
-
吞吐量throughput:JVM总共运行了100分钟,其中垃圾收集花掉1分钟,那吞吐量就是99%,即(all-gc)/all(for batch pipeline)
-
停顿时间:垃圾回收器正在运行时,应用程序的暂停时间(for streaming pipeline)
回收器类型
-
NEW
-
serial,单线程
-
parNew,serial多线程版
-
Parallel Scavenge,复制算法,并行,优先保证吞吐量,不顾及用户STW感受,吞吐量方面优化的系统,停顿时间长是可以接收的。
-
OLD/tenured
-
Serial Old,Serial回收器的老年代版本,单线程,标记-整理算法
-
Parallel Old,Parallel Scavenge回收器的老年代版本,多线程,标记-整理算法
-
Concurrent Mark Sweep, CMS:优先最短回收停顿时间,用户体验好,标记-清除算法
-
NEW and OLD
-
关键点:region内存划分,优先级区域回收方式。优先回收价值最大的region
-
garbage first, G1:它将整个Java堆划分为多个大小相等的独立区域(Region),虽然还保留有新生代和老年代的概念,但新生代和老年代不再是物理隔离的了,它们都是一部分Region(不需要连续)的集合。