JVM(Java虚拟机)是由:一套字节码指令集、一组寄存器、一个栈、一个垃圾回收堆和一个存储方法域等组成。
一、java类加载过程
注:加载、验证、准备、解析、初始化、使用和卸载,等7个阶段,验证、准备、解析3个部门统称为连接
1、加载:负责找到二进制字节码并加载到jvm 中,JVM 通过类名、包名、ClassLoader 完成类的加载。
2、链接:对二进制字节码的格式进行校验、初始化装载类中的静态变量以及解析类中调用的接口。完成校验后,jvm 初始化类中静态变量,并将其赋值为默认值。最后对比类中的所有属性、方法进行验证,以确保要到用的属性、方法存在,以及具备访问权限(private、public)。
3、初始化:负责执行类中的静态初始化代码、构造器代码以及静态属性的初始化,初始化过程被触发:①调用new ②反射调用类中的方法③子类调用了初始化④JVM启动过程 初始化主类。
二、Java运行时数据区
JVM内存共分为 虚拟机栈、堆、方法区、程序计数器、本地方法栈 五部分。
内存空间中按照是否线程共享分两块。共享:方法区(method area) 和 堆 (heap),线程独享:虚拟机栈(VM stack),本地方法栈(native method stack)和程序计数器(program counter register)
1、虚拟机栈(线程私有)
每个线程有一个私有的栈,随着线程的创建而创建。栈里面存放着“栈帧”的东西,每个方法在执行的时候会创建一个栈帧,存储了局部变量表(基本数据类型和对象的引用),操作数栈,动态链接,方法出口等信息。每个方法从调用到执行完毕,对应一个栈帧在虚拟机栈中的入栈和出栈。通常所说的栈,一般是指虚拟机栈中的局部变量表部分。局部变量表所需的内存在编译期间完成分配。栈的大小可以固定也可以动态扩展,当扩展到无法申请足够的内存,则OutOfMemoryError。当栈调用深度大于JVM 所允许的范围,会抛出 stackOverFlowerror的错误,不过这个深度范围不是一个永恒不变的值。
2、本地方法栈(线程私有)
和虚拟机栈类似,主要为虚拟机使用到的Native方法范围。也会抛出 StackOverflowError和OutOfMemoryError.
3、PC 寄存器(线程私有)
PC 寄存器也叫程序计数器。JVM 支持多个线程同时运行,每个线程都有自己的程序计数器。倘若当前执行的是JVM方法,则该寄存器中保存当前执行指令的地址;倘若执行的是native方法,则PC寄存器为空。这个内存区域是唯一一个在虚拟机中没有规定任何OutOfMemoryError 情况的区域。
4、堆(线程共享)
堆内存是JVM所有线程共享的部分,在虚拟机启动的时候就已经创建。和程序开发密切相关,应用系统对象都保存在java堆中。所有的对象和数组都在堆上面进行分配。这部分空间可通过GC进行回收。对分代GC来说,堆也是分代的,是GC的主要工作区间。当申请不到的时,会抛出OutOfMemoryError。
5、方法区(线程共享)
方法区也是所有线程共享的。主要用于存储类的信息、常量池、方法数据、方法代码等。方法区逻辑上面属于堆的一部分。但是为了与堆进行区分,通常又叫 “非堆”。
这个区域的内存回收目标主要针对常量池的回收和对类型的卸载。
当方法区无法满足内存的分配需求时,则抛出 OutOfMemoryError异常。
在HotSpot 虚拟机中,用永久代来实现方法区,将GC分代收集扩展至方法区,但是这样容易遇到内存溢出问题。
JDK1.7中,已经把放到永久代的字符串常量池移到堆中。
JDK1.8撤销永久代,一如元空间。
三、元空间和永久代
元空间的本质和永久代类似,都是对JVM规范中的方法区的实现。不过元空间与永久代最大的区别在于:元空间并不在虚拟机中,而是使用本地内存。因此,默认情况下,元空间的大小仅受本地内存现在,但是可以通过以下参数来指定元空间的大小:
-XX:MetaspaceSize,初始空间大小,达到该值就会触发垃圾收集进行类型卸载,同时GC会对该值进行调整:如果释放了大量的空间,就适当降低该值;如果释放了很少的空间,那么在不超过MaxMetaspaceSize时,适当提高该值。
-XX:MaxMetaspaceSize,最大空间,默认是没有限制的。
除了上面两个指定大小的选项以外,还有两个与 GC 相关的属性:
-XX:MinMetaspaceFreeRatio,在GC之后,最小的Metaspace剩余空间容量的百分比,减少为分配空间所导致的垃圾收集
-XX:MaxMetaspaceFreeRatio,在GC之后,最大的Metaspace剩余空间容量的百分比,减少为释放空间所导致的垃圾收集
参考:https://juejin.im/post/6844903881063792647,https://juejin.im/post/6844903693645512717