JVM类加载器,运行时数据区和GC算法

前言:
本文章知识简单对JVM东西做了总结,不是很全面,但是后期会再补充.
适合新手小白阅读.

JVM类加载器

四种类加载器

作用:主要负责加载.class文件

1.自定义类加载器 必须继承ClassLoder才可以使用自定义类类加载器

2.应用类加载器 AppClassLoder 主要负责加载的是程序中的主函数

3.扩展类加载器 ExtClassLoder 主要负责加载的是扩展类库 jre/lib/ext下的jar包

4.启动类加载器(根类加载器)BootStrapClassLoder 主要负责加载的是核心类库(java.lang.*等) jre/lib/rt 下的jar包,构造ExtClassLoder和AppClassLoder

AppClassLoder >(父类) ExtClassLoder>(父类)BootStrapClassLoder

双亲委派机制

作用:

1.保证JDK核心类库优先被加载.

2.防止同一个.class被重复加载,保证数据安全

3.保证核心.class不能被进行篡改

扫描二维码关注公众号,回复: 11714554 查看本文章

具体流程如下图:
在这里插入图片描述

  1. 类加载器收到类加载请求

  2. 向上委托给它的父类,一直向上委托,知道委托给启动类加载器

  3. 启动类加载器区进行加载这个类,如果能进行加载,则结束,使用此加载器进行加载,如果不能进行加载,则抛出异常,通知其子类去进行加载

  4. 如果都无法加载此类,则抛出异常,Class Not Found异常,表示找不到这个类.

JVM类加载过程

在这里插入图片描述

加载阶段

1 通过一个类的全限定名获取定义此类的二进制字节流

2 将这个字节流所代表的静态存储结构转换为方法区的运行时数据结构

3 在内存中生成一个代表这个类的java.lang.class对象,作为方法区这个类的各个数据的访问入口

连接阶段

(分为三部分验证===>准备===>解析)

1 .验证阶段

确保Class文件的字节流中包含的信息符合当前虚拟机的需求,并且不会危害到虚拟机自身安全。其包含四种验证,文件格式验证,元数据验证,字节码验证,符号引用验证。

文件格式验证:主要验证字节流是否符合Class文件格式规范,并且能被当前虚拟机加载处理.

元数据验证:对字节码描述的信息进行语义的分析,分析是否符合java语言的语法规范.

字节码验证:主要针对方法体的验证,确保类方法在运行时不会有危害.

符号引用验证:主要是要保证引用一定会被访问到,不会出现类等无法访问的问题.

2.准备阶段

类准备阶段负责为这个类的静态变量分配内存,并设置默认初始值

3.解析

将类的二进制数据中的符号引用替换成直接引用

符号引用:符号引用是以一组符号来描述所引用的目标,符号可以是任何字面形式的字面量,只要不出现冲突能够定位到就行

直接引用:是指向目标的指针,该引用是和内存中的布局有关并且一定加载进来的

初始化阶段

以上所有阶段除了加载阶段,可以自定义类加载器,其他都是由JVM主导的,初始化阶段才是真正开始执行java代码,初始化阶段是执行类构造器方法的过程

类构造器clinit

方法是由编译器自动收集类中的类变量的赋值操作和静态语句块中的语句合并而成的。虚拟机会保证子方法执行完,父类的方法已经执行完毕.

如果一个类中没有静态变量赋值也没有静态语句块,那么编译器可以不为这个类生成方法

·在什么情况类不会进行初始化阶段

  1. 定义对象数组时,不会触发类的初始化

  2. 通过类名获取Class对象,不会触发类的初始化.

  3. 通过ClassLoder默认的loadClass方法,也不会触发初始化.

    等等.(这里只是简单的说了几点,其实还有很多,知道部分即可)

运行时数据区

在这里插入图片描述

线程私有区域(不会有垃圾)

本地方法栈

早期C和C++一直都存在,直到JAVA的出现,它想要调用其他语言的类库,于是就在内存中开辟出一个专门的区域,这个区域叫做本地方法栈,本地方法栈是专门为native进行服务的,当使用native关键字进行修饰,就说明java作用范围达不到,会去调用JNI,也就是本地方法接口,本地方法库里面主要包含的是其他语言的方法,它会传送数据给本地方法接口.
在这里插入图片描述

虚拟机栈

虚拟机栈也叫java栈,它是一个先进后出,后进先出的一个过程,它主要负责程序的运行,线程的生命周期和线程同步。栈里面不会存在垃圾,因为当程序结束了,栈也就结束了,所以它里面是不会存在垃圾的.

它主要存储的是8大基本类型+对象的引用+方法的实例,它记录了入栈到出栈的过程(本博客没有具体涉及讲述栈帧).

栈溢出

如果线程请求的栈深度大于虚拟机所允许的深度,会报出java.lang.StackOverflowError

解决方法:设置线程的最大调用深度

-Xss 设置最大调用深度

程序计数器(PC寄存器)

每一个程序都会有一个程序计数器,是线程私有的,也就是一个指针,指向方法区的字节码(用来存储下一条指令的地址,也就是将要执行的指令代码)在执行引擎读取下一条指令.它是极小的一块区域,占用内存几乎可以忽略不计.

线程共享区域(存在垃圾)

堆里面存放的是类,方法,常量,变量的实例.

·堆内存主要还分为二个区域

新生代

​ Eden 伊甸园区

​ 幸存者0区(From)

​ 幸存者1区(To)

默认的比例是8:1:1,保证GC的时候复制存活的对象有个存储的地方。

新New出来得对象会存放在伊甸园区

From和To的两个交换区(Survivor区),只有一个区有数据,每次只用一个,和Eden一起进行使用,当触发回收时,将存活的对象统一复制到另一个交换区,然后对Eden区和本survivor区直接清理掉,当survivor区不够时,会向老年代借用空间,就是所谓的分配担待。

当伊甸园区内存快不够的时候,也就是快要满的时候,新生区会进行轻量的垃圾回收,也就是轻GC(Minor GC)

老年代

长期存活的对象会进入到老年代

年龄阈值:每个对象定义了年龄计数器,经过一次Minor GC(在交换区)后年龄加1。对象年龄达到15次后晋升为老年代。

大对象会直接进入到老年代 表示超过Eden剩余空间

动态年龄判断:如果在Survivor空间中,相同年龄所有对象大小的总和大于Survivor的空间一半,那么大于或等于此年龄的对象直接进去老年代,无需等待晋升!

当老年代存放的对象过多了,说明堆里面的垃圾很多了,就会进行重量级的GC垃圾回收。也就是重GC(Full GC)

方法区

静态变量(static)、常量(final)、类信息(构造方法、接口定义)、运行时的常量池存在方法区中,但是实例存在堆内存中,和方法区无关

元空间

1.6之前叫做永久代 存放在方法区中

1.7也叫永久代 但是存放在堆中了

1.8之后(移除永久代)叫做元空间 常量池存放在元空间中

GC垃圾回收机制

java堆,元数据区,直接内存

GC Root内存不够时才需要垃圾回收

如何判断垃圾是否可以回收

**引用计数法:**为每个对象分配计数器,每当对象使用加1,为0则清除,后来出现弊端,当两个对象相互引用就不会被回收,而且为每个对象分配计数器太复杂和麻烦.

**可达性分析:**通过一系列的称谓“GC Roots”的对象作为起始点,从这些节点开始向下搜索,搜索所有走过的路径为引用链,当一个对象到GC Roots没有任何引用链项链时,则证明此对象时不可用的。

那些可以作为GC Root对象

·虚拟机栈中的引用对象

·方法区静态变量引用对象

·常量引用对象

垃圾回收常用算法

没有最好的算法,只有最合适的算法.

复制算法

将需要的信息复制到预留的内存,然后对原先得内存进行垃圾回收,每次保证一个幸存区为空。

好处:没有内存碎片

坏处:浪费空间,有一部分永远是空的。

最好的使用场景是对象存活较低的情况下(新生区)
在这里插入图片描述
在这里插入图片描述
从图上我们可以看出To区和From区是一个动态的概念,每次都会保留To区为空,清理Eden区和From区,清理后存活对象放在From区,等待下次Eden区快满进行Minor GC.

标记-清除

扫描对象,对存活的进行标记,清除未被标记的对象

优点:不需要额外的空间

缺点:两次扫描,严重浪费时间,还会产生内存碎片
在这里插入图片描述

标记-整理

对标记-清除算法进行了优化,防止内存碎片的产生,再次扫描,向一端移动存活的对象,多了个移动的成本

在这里插入图片描述
从图上我们也能看出标记-整理算法是非常耗费时间的,因为它比其他算法所有的步奏都要多.

分代算法

之前一直采用的都是分区算法,但是现在都是采用的分代算法,分代相当于所有的算法的集合.

没有最好的算法,只有最合适的算法

年轻代:存活率低,考虑使用复制算法

老年代:区域大:存活率高,考虑使用标记清除算法+标记压缩混合实现(调优主要针对执行多少次标记清除后,执行标记压缩)

内存效率:复制算法>标记清除算法>标记压缩算法(时间复杂度)

内存整齐度:复制算法=标记压缩算法>标记清除算法

内存利用率:标记压缩算法=标记清除算法>复制算法

总结:这些都是自己学习的,不是太深入,有些太深入的东西没有涉及到,可以先考虑学习,后期可以发布一个垃圾收集器,栈帧,JMM等这些知识的总结!每个人的理解都是不一样的,我也希望大家能通过这篇文章,总结出来自己对JVM的一些简单理解,希望对大家有帮助!加油!

猜你喜欢

转载自blog.csdn.net/qq_46169471/article/details/108607080