首页 > 系统相关 >快速认识JVM,深入掌握类加载器、JVM内存空间、JVM垃圾回收机制和双亲委派机制。

快速认识JVM,深入掌握类加载器、JVM内存空间、JVM垃圾回收机制和双亲委派机制。

时间:2024-08-12 21:59:32浏览次数:12  
标签:对象 内存空间 回收 静态 内存 JVM 机制 加载

什么是JVM

        JVM(Java Virtual Mchine)java虚拟机,主要作用就是将Java字节码文件解释为能被各种操作系统理解的机器码

JVM的三大功能

        1.解释和运行:将字节码文件翻译为能被各种操作系统理解的机器码。

        2.内存分配:给对象及其方法分配内存,管理对象。

        3.即时编译(JIT):将热点代码编译为字节码放到内存中,提高效率。

类加载器ClassLoad

类的生命周期

类的加载阶段:

        将类的信息(硬盘、网络、反射)以二进制的形式加载到内存中。

 注意:具体放在InstanceKlass(c语言编写)中,但因为Java程序不便直接操作c语言程序,所以使用Java.lang.Class进行映射。通过操作Java.lang.Class来控制InstanceKlass。

类的连接阶段:

        连接阶段分为:验证、准备、解析。主要作用是验证Java代码是否符合规范、静态变量赋初始值(并不是直接赋原本变量值,而是赋0、1这种初值。final修饰变量在此阶段赋值)、将符号引用转变为内存地址值。

类的初始化阶段:

        初始化阶段主要是给静态变量赋真值、执行静态方法(final修饰的静态变量在连接节段的准备状态中赋值)。

        是否触发初始化,访问静态变量就会初始化。记住两个特例:final修饰的静态变量(final修饰静态变量赋值不为常量除外)、创建数组的类不会初始化。

触发初始化的情况:

  1. 使用Class.forName(),反射加载类
  2. 访问静态变量,访问final修饰的静态变量除外   
  3. new对象
  4. 访问final修饰的静态变量右边不是常量,会初始化(特殊情况)

不触发初始化的情况:

  1. 无静态代码块或无静态变量赋值语句
  2. 有静态变量,但是没有赋值
  3. 使用final关键字修饰的静态变量(final修饰的静态变量右边不是常量除外
  4. 创建数组的类,类本身不会初始化(特殊情况

类加载器

双亲委派机制(重点)

什么是双亲委派机制?

        加载类时,向父类寻找是否加载过该类,如果加载过类直接返回加载过的类,避免重复加载。寻找到启动类加载器后,从启动类加载器向下加载该类,保证加载类时的优先级顺序。

        Application的父类是Extension,Extension加载器的父类是BootStrap。

双亲委派机制的优点:

        1.避免恶意修改JDK的核心类库

        2.避免类被重复加载

如何打破双亲委派机制

为什么要打破双亲委派机制?

        双亲委派机制中类加载都是由Application、Extension、BootStrap加载,这样做不够灵活。例如在高度模块化的组件中,每个模块有自己的类加载器,操作自己的类加载器进行热操作,不去影响其他模块,这样操作更灵活。

如何打破双亲委派机制?

注意:

1.如果想实现自定义的类加载器,但是不想打破双亲委派机制,可以重写findClass方法。

2.类加载器和全限定类名相同,在Java中才会被认为是一个类。(类加载器不同,类名相同不是一个类)

重写ClassLoad类中loadClass()方法

双亲委派机制的核心逻辑,只要我们将这段代码重写就可以打破双亲委派机制

protected Class<?> loadClass(String name, boolean resolve)

 synchronized (getClassLoadingLock(name)) {

 Class<?> c = findLoadedClass(name);

    if (c == null) {
     if (parent != null) {
       c = parent.loadClass(name, false); //当前类加载器没有加载到类,就去父类寻找
      } else {
        c = findBootstrapClassOrNull(name);
         }
       }

JVM内存区域(重点)

JVM内存区域,各空间详解

线程不共享区

程序计数器:程序计数器记录当前线程字节码执行位置。作用是,在线程切换后该线程可以继续执行之前因线程切换而未完成的任务。

栈(当方法递归执行时会造成内存泄漏):通过(先进后出)来记录方法栈帧。方法栈帧包括局部变量表(存放局部变量)、操作数栈(存放临时数据)、帧数据(变量内存地址/动态链接、方法出口、异常表)。

本地方法栈:记录本地方法的方法栈帧。

线程共享区

(创建过多对象时会造成内存泄漏):存储对象、数据、集合。(重点是堆的垃圾回收)

方法区:储存类信息运行时常量池(放置在元空间中)、字符常量池(堆内存)。

JVM垃圾回收(重点)

如何判断可以垃圾回收的内存区域

引用计数法:给对象添加计数器,统计对象引用次数,如果为0表示没有引用该对象可以回收。存在的问题是,两个对象相互引用就无法回收。

可达性分析法(JVM采用方案):将对象分为两类,GCroot对象普通对象;如果普通对象的引用路线中有GCroot对象,就不会被回收。

GCroot对象包括:

  1. 线程对象
  2. java.lang,Class对象
  3. 监视器对象,,用来保存同步锁synchronized关键字持有的对象
  4. 本地方法栈中的全局变量

JVM垃圾回收算法

标记清除算法:标记不可回收空间,删除其他对象所占空间。

优点,实现简单;缺点,产生内存碎片

复制算法:将内存空间分为From,To两片空间。每次GC时会将不可回收对象放到To空间中,然后将To改为From(From改名为To,确保From永远存储不可回收对象)。

优点,解决内存碎片;缺点,空间利用效率低(只能利用一半内存)

标记整理算法:标记不可回收空间,并将这些空间转移到同一端,删除其他对象内存空间。

优点,解决内存碎片;缺点,需要执行多次空间转移算法时间利用率低

分代GC(重点)

分代GC中堆空间内存图

分代GC过程中对象经历的全过程(这是小编呕心沥血画的示意图,友友们觉着不错快点赞吧!)

G1垃圾回收器(重点)

G1垃圾回收器的特点:

  1. 将内存区域划分为Region,区域不连续而是独立的小块。     
  2.   支持多核CPU并发进行垃圾回收。
  3. 允许自主设置最大停止时间(G1通过判断Eden、Survivor区回收时间进行预估)

G1垃圾回收算法:

G1判断内存空间占年轻代60%,触发youngGC,回收年轻代内存,采用复制算法。

G1判断内存空间占总堆的45%,触发MixedGc,回收年轻代+老年代内存,采用复制算法。

G1判断内存空间占满,触发fullGC,回收年轻代+老年代内存,采用标记整理法。

并发垃圾回收过程

第一步:初始标记GCroot对象,阻塞执行。

第二步:标记GC存活对象并发执行。

第三步:最终标记的是标记GC存活对象并发过程中所修改的对象,不去管理新创建或者不再关联的对象,阻塞执行

第四步:并发清除垃圾对象并发执行

标签:对象,内存空间,回收,静态,内存,JVM,机制,加载
From: https://blog.csdn.net/weixin_62440319/article/details/141021120

相关文章

  • 记一次 JVM 崩溃问题排查(G1 日志分析)
    背景上周五业务高峰期,有一个java实例毫无征兆的crash了,第一时间应用重启之后,将对应的崩溃日志保留,后面做分析。先说一下该服务的具体情况:jdk版本:1.8.0_152-b16服务器信息:16C32G启动参数:-Xms18g-Xmx18g-Xss256k-XX:MetaspaceSize=256m-XX:MaxMetaspaceSize=512m-XX:......
  • 三层架构与解耦——IoC&DI机制【后端 7】
    三层架构与解耦——IoC&DI机制在软件开发领域,三层架构(Controller、Service、Dao)是一种广泛采用的架构模式,它通过将应用程序分为三个主要层次来组织代码,旨在提高代码的可维护性、复用性和可扩展性。而解耦(Decoupling)则是实现这些目标的关键技术之一。本文将深入探讨三层架......
  • 解锁《终结者:幸存者》新玩法:Steam家庭共享机制详解与实战指南
    在Steam平台上,玩家可以通过家庭共享功能,与亲朋好友共享自己购买的游戏库,包括《终结者:幸存者》这款游戏。以下是对Steam家庭共享机制的详细解析与实战指南:一、Steam家庭共享基本概念Steam家庭共享功能允许一个Steam账号在其许可的范围内,最多与其他5个Steam账号共享游戏库。这......
  • JDK自带命令:深入理解Java程序的运行机制
    JDK(JavaDevelopmentKit)是Java开发和运行环境的核心,它提供了丰富的命令和工具来帮助我们更好地理解和控制Java程序的运行。本文将详细介绍JDK自带的一些关键命令,以及它们的详细参数和执行结果。1.jps(JavaVirtualMachineProcessStatusTool)jps命令用于列出正在运行的......
  • JVM参数详解:优化应用程序性能的关键
    Java虚拟机(JVM)是Java程序的运行环境,它负责将Java字节码转换为机器码,并在实际计算机上执行。为了优化应用程序的性能,我们需要了解JVM的参数设置。本文将详细介绍JVM的常见参数及其作用,帮助您更好地理解和配置JVM。JVM参数分类JVM参数分为两大类:启动参数和系统属性。1.启......
  • JVM内存结构的划分
    5.3JVM内存结构的划分5.3.1栈(保存局部变量和方法调用的信息)栈也是线程私有的,在我们调用方法的时候,每调用一个方法,该方法就会进入栈中,当该方法执行完毕的时候就会从栈中移除。比如说现在要在main方法中调用A方法,在A方法中再调用B方法:但是,如果我们不停的调用方法,就会导致栈满......
  • Java学习笔记1--JDK,JRE和JVM
    1、Java开发环境Java开发环境是指Java程序员开发、编写、测试和调试Java程序所使用的所有工具和技术。Java开发环境通常由以下几个部分组成:JDK(JavaDevelopmentKit):JDK是Java开发环境的核心组件,它包括了Java编译器、JRE(Java运行环境)、JavaDoc文档生成器和其他一些工具。JDK是J......
  • 云中韧性:Spring Cloud服务调用重试机制深度解析
    标题:云中韧性:SpringCloud服务调用重试机制深度解析在微服务架构中,服务间的调用可能会因为网络问题、服务不可达、资源竞争等原因失败。SpringCloud作为微服务架构的主流实现框架,提供了一套完整的服务调用重试机制,以增强系统的健壮性和可靠性。本文将详细探讨SpringCloud......
  • Linux:线程同步机制(互斥锁、读写锁、条件变量、信号量详细分析总结)
    目录速览1、互斥锁(1)What(什么是互斥锁)(2)Why(互斥锁的用途)(3)How(如何使用互斥锁)(4)代码实践2、读写锁(1)What(什么是读写锁)(2)Why(读写锁的作用)(3)How(如何使用读写锁)(4)读写锁的特征3、条件变量(1)What(什么是条件变量)(2)Why(条件变量的作用)(3)How(如何使用条件变量实现线程......
  • js的原理(运⾏机制)
    ⾸先js是单线程运⾏的,在代码执⾏的时候,通过将不同函数的执⾏上下⽂压⼊执⾏栈中来保证代码的有序执⾏。在执⾏同步代码的时候,如果遇到了异步事件,js引擎并不会⼀直等待其返回结果,⽽是会将这个事件挂起,继续执⾏执⾏栈中的其他任务所有任务可以分成两种,⼀种是同步任务(synchrono......