JVM知识总结

发布于:2024-12-06 ⋅ 阅读:(34) ⋅ 点赞:(0)

1.内存模型以及分区

  • 方法区:主要存储已被加载的类信息,常量,静态变量等。例如,一个类的字节码信息,类的常量池以及静态变量都会存储在方法区中。在Java8之后,方法区被元空间取代,使用本地内存,不再受限于JVM内存大小。
  • 堆:堆是JVM内存中最大的一块,用于存储对象实例和数组。所有的对象和数组的内存分配都在堆上进行。例如,当我们new一个对象时,这个对象就会在堆中分配内存空间。
  • Java虚拟机栈:每个Java方法在执行时豆毁创建一个栈帧,用于存储局部变量表,操作数栈,动态连接,方法出口等信息。当一个方法被调用时,一个新的栈帧就会被压入栈中;当方法执行完成后,栈帧就会被弹出。
  • 本地方法栈:和Java虚拟机栈类似,但是它是为本地方法服务的。本地方法是指用非Java语言编写并且可以被java程序调用的方法。当执行本地方法时,就会在本地方法栈中创建相应的栈帧。
  • 程序计数器:是一块较小的内存空间,它可以看作是当前线程所执行的字节码的行号指示器。在多线程环境下,每个线程都有自己的独立程序计数器,用于记录当前线程执行到字节码的位置。

2.类加载的流程

  1. 加载:类加载器获取字节码文件并将字节码文件转化为二进制字节流,然后在内存中生成代表该类的class对象。
  2. 验证:文件格式验证:检查字节码文件是否符合Java虚拟机规范的格式要求。元数据验证:对字节码所描述的类的元数据进行验证。字节码验证:验证字节码指令的合法性。确保字节码中的操作数和操作码的组合是有效的。例如,不能出现非法的跳转指令。符号引用验证:当一个类引用了其他类的方法,字段,或者接口时,会进行符号引用验证。主要检查这些引用是否可以正确解析到对应的类,方法,字段等。
  3. 准备:给类对象分配内存空间,但是并没有初始化。
  4. 解析:将类,接口,方法,字段的符号引用转化为直接引用。例如:当一个类 A 引用了类 B 的一个方法,在解析阶段会把字节码中对类 B 方法的符号引用转换为实际的内存地址或者其他可以直接定位到这个方法的引用,这样在执行这个引用时就可以直接找到对应的方法。
  5. 初始化:执行静态初始化块和静态变量的赋值,初始化父类,设置类的初始化状态已完成。

3.双亲委派模型

定义

是Java类加载器的一种工作机制。在这个模型中,类加载器之间存在一种层次关系,除了顶层的启动类加载器(Bootstrap Class Loader)外,其他的类加载器都有一个父类加载器。当一个类加载器收到类加载请求时,它会首先把这个请求委派给它的父类加载器去完成,只有父类加载器无法完成这个加载请求时,子加载器才会尝试自己去加载。

类加载器的层次结构

  • 启动类加载器(Bootstrap Class Loader):它是最顶层的类加载器,主要负责加载Java核心类库,如java.lang包下的类。
  • 扩展类加载器(Extension Class Loader):它的父类是启动类加载器。主要负责加载java的扩展类库。例如一些java的标准扩展功能(javax.swing等部分组件)
  • 应用程序类加载器(Application Class Loader):也被称为系统类加载器,它的父类加载器是扩展类加载器,主要负责加载用户自定义的类路径下的类,也就是我们日常开发中自己编写的类。

工作流程

假如我们在自己的java应用程序中创建了一个java.lang.String类,当应用程序类加载器收到加载类请求时,会先委派给扩展类加载器,扩展类加载器又会委派给启动类加载器,因为这个类是java核心类库中的类,启动类加载器能找到并且加载这个类,所以最终这个类是由启动类加载器加载的。

4.GC垃圾回收

概念:

垃圾回收是java虚拟机自动管理内存的一种机制,在Java程序运行过程中,会不断创建对象,这些对象会占用内存空间,当对象不再被使用时,GC负责识别并回收这些对象所占用的内存,为新创建的对象腾出内存空间。

判断对象是否为垃圾的方法

  • 引用计数法:为每个对象添加一个引用计数器,当有一个地方引用这个对象时,计数器加一,当引用失效时,比如引用变量超出作用域或者被赋值为其他对象时,计数器减一,当计数器的值为0,就认为这个对象是垃圾,可以被回收。但是无法解决循环引用的问题。
  • 可达性分析:有一个或一组线程周期性的扫描我们代码中所有的对象,从一些特定的对象出发,尽可能的进行访问遍历,把所有能访问到的对象都标记成“可达”,反之经过扫描之后,没有被标记的对象就是垃圾了(可达性分析的出发点有很多,不仅仅是所有的局部变量,还有常量池中引用的对象,还有方法区中的静态变量引用的对象)。但是比较消耗系统资源,开销较大。

垃圾回收算法

  1. 标记清除算法:从特定对象开始,通过可达性分析所有可达对象,未被标记的对象就是垃圾对象,回收未被标记对象所占用的内存空间。但会产生内存碎片
  2. 复制算法:将内存划分为大小相等的两块区域,比如a,b每次只使用其中一块,比如使用a区域,当进行垃圾回收时,把a中的存活对象复制到b区域,,然后情况区域a的所有内容。但会浪费内存空间。
  3. 标记整理算法:标记阶段和标记清除算法一样,整理阶段,将所有存活的对象向前搬运,然后清理后面的垃圾。

垃圾回收器类型

  1. Serial垃圾回收器:单线程垃圾回收器,在进行垃圾回收时,会暂停所有的用户线程,直到垃圾回收过程结束。
  2. Parallel垃圾回收器:也称为吞吐量优先垃圾回收器,它使用多个线程同时进行垃圾回收,能够提高垃圾回收的效率,减少垃圾回收的时间,但是同样会暂停用户线程。
  3. CMS垃圾回收器:一种并发的垃圾回收器,主要目标时尽力减少垃圾回收的时间,他在垃圾回收的部分阶段(标记阶段)可以和用户线程同时运行。
  4. G1垃圾回收器:将堆内存划分为多个大小相等的区域,在进行垃圾回收时,可以根据各个区域中垃圾的多少来灵活地选择回收区域。能在一定程度上控制垃圾回收的停顿时间,并且可以同时兼顾垃圾回收的吞吐量。

5.堆的分区

  • 新生代:新生代是堆内存中的一个区域,主要用于存放新创建的对象
  1. 伊甸区:是对象最初诞生的地方。当我们在java程序中new一个对象时,这个对象首先会被分配到伊甸区。
  2. 幸存区:分为两个区域;,大小相同,主要用于存放从伊甸区经过一次垃圾回收后仍然存活的对象,然后将这些存活的对象复制到另一个幸存区。
  • 老年代:主要用于存放经过多次垃圾回收后仍然存在的对象,这些对象通常生命周期较长,比如缓存对象,单例对象。

 


网站公告

今日签到

点亮在社区的每一天
去签到