JVM基础了解
1、JVM的位置
运行在操作系统上
2、JVM的体系结构
3、类加载器
- 虚拟机自带加载器
- 启动类(根)加载器(c++编写,加载java核心库,开发者无法直接获取到启动类加载器的引用)
- 扩展类加载器(
java
编写,加载扩展库) - 系统类加载器(
java编写,加载程序所在的目录
) - 用户自定义类加载器(
java
编写,用户自定义的类加载器,可加载指定路径的class
文件)
4、双亲委派机制
当某个类加载器需要加载某个.class文件时,会先委托上级类加载器,递归这个操作,如果上级类加载器的加载路径没有该类,才会用自己加载这个类
作用:保证核心类的安全,如果自定义的类与核心类的全限定类名相同,不会加载该类并会抛出异常
5、Native
native关键字,表示通过本地方法接口(JNI:java native interface),调用底层C语言的库
6、PC寄存器
程序计数器:Program Counter Register
每个线程都有一个程序计数器,是线程私有的,就是一个指针,指向方法区中的方法字节码(用来存储指向下一条指令的地址,也即将要执行的指令代码),由执行引擎读取下一条指令,是一个非常小的内存空间,几乎可以忽略不记。
7、方法区
方法区被所有线程共享,所有字段和方法字节码,以及一些特殊方法,如构造函数,接口代码也在此定义,简单说,所有定义的方法的信息都保存在该区域,此区域属于共享区间;
静态变量、常量、类信息(构造方法、接口定义)、运行时的常量池存在方法区中
8、栈(Stack)
栈存放:局部变量、对象的引用、方法
栈溢出会抛出StackOverflowError错误
9、堆(Heap)
一个JVM只有一个堆内存,堆内存的大小可以调节。
堆内存分为三个区域:
- 新生区(对象在这里创建,也可能销毁)
- 伊甸园区:所有对象都是在伊甸园区new出来的
- 幸存区0区
- 幸存区1区
- 老年区
- 永久区(JDK8后改为:元空间)
GC(Garbage Cellection)垃圾回收,主要在伊甸园区和老年区。
如果内存都满了,就会报OOM(java.lang.OutofMemoryError: Java heap space)错误!
10、GC算法
- 复制算法:将内存划分为两块,每次只用其中一块内存,当这一块内存用完了就将存活的对象复制到另一块内存,其余的清理掉
- 优点:简单高效,没有内存碎片问题
- 缺点:需要两倍的内存空间(空间换时间)
- 标记清除算法:GC分为两个阶段,标记和清除。首先标记所有可回收的对象,在标记完成后统一回收所有被标记的对象
- 优点:节省内存空间
- 缺点:会产生不连续的内存碎片。碎片过多会导致以后程序运行时需要分配较大对象时,无法找到足够的连续内存,而不得已再次触发GC
- 标记清除压缩算法:也分为两个阶段,首先标记可回收的对象,再将存活的对象都向一端移动,然后清理掉边界以外的内存
- 优点:节省内存空间,避免了标记-清除算法的碎片问题,同时也避免了复制算法的空间问题
- 缺点:需要比标记清除算法多扫描一次(时间换空间)
分代收集算法:一般新生区存活率较低会采用复制算法,而老年区存活率较高采用标记清除算法或标记清除压缩算法!