首页 > 其他分享 >jvm调优第二天——类加载机制(有面试问题)

jvm调优第二天——类加载机制(有面试问题)

时间:2024-09-26 11:51:12浏览次数:10  
标签:Java jvm 自定义 应用程序 调优 JVM 父类 加载

1.类加载机制简介:       

        Java虚拟机(JVM)的类加载机制是Java应用程序性能调优的关键组成部分。类加载机制不仅负责将类从磁盘加载到内存中,还涉及到类的链接、初始化以及内存管理。本文旨在探讨JVM类加载机制的工作原理,以及如何通过调优类加载过程来提升Java应用程序的性能。

2.类加载过程:    

        在Java应用程序的生命周期中,类加载机制扮演着至关重要的角色。它确保了应用程序的类在需要时被加载,并且在适当的时候被卸载。JVM的类加载过程包括加载、链接、初始化三个主要阶段。了解这些阶段的工作方式对于进行有效的JVM调优至关重要。

2.1加载阶段

        在加载阶段,JVM通过类加载器读取.class文件的二进制数据,并将其转换成一个java.lang.Class对象。这个对象代表了该类在JVM中的一个类定义。

(1)获取类的全限定类名,把class文件转为二进制流

(2)将二进制流中类的描述信息存入方法区中。如:创建时间、版本等...

(3)将java.lang.Class 对象存入堆中。

2.2链接阶段

        链接阶段包括验证、准备和解析三个子阶段。验证阶段确保加载的类信息符合JVM规范;准备阶段为类的静态变量分配内存并设置默认初始值;解析阶段将类、接口、字段和方法的符号引用转换为直接引用。

(1)验证:验证被加载类的正确性:如文件的格式,元数据等。

(2)准备:在方法区中为静态变量分配空间,并设置初始值。 

(3)解析:把类的符号引用转为直接引用。 符号引用:class文件定义的内容 直接引用:JAVA进程中真实的地址

2.3初始化阶段

        在初始化阶段,JVM执行类的静态初始化器和静态变量的赋值操作。这个阶段是类加载过程中耗时最长的阶段,因为JVM需要执行类构造器<clinit>()方法

        为类的静态变量设置默认值、执行静态代码块。初始化就是执行类的构造器方法init()的过程。这个方法不需要定义,是javac编译器自动收集类中所有类变量的赋值动作和静态代码块中的语句合并来的。

        注意:若该类具有父类,jvm会保证父类的init先执行,然后在执行子类的init

3.类加载器:

        什么是类加载器?类加载器是Java虚拟机(JVM)的一个核心组件,负责将类(.class文件)加载到JVM中。在Java中,每个类都由特定的类加载器加载,这是实现Java应用程序模块化和封装的一种机制。类加载器不仅加载类,还负责链接(验证、准备、解析)和初始化类。

3.1类加载器的分类

        不同的类加载器加载不同的类:

        启动类加载器(BootstrapclassLoader): 主要负责加载JAVA中的 一些核心类库,用C++实现,是虚拟机自带的类加载器。负责加载JAVA_HOME/jre/lib目录中的核心类库,如rt.jar、jsse.jar等,不属于java.lang.ClassLoader的子类。

        拓展类加载器(Extension classLoader):主要加载 JAVA 中的一些拓展类,用Java语言实现,继承自ClassLoader类。负责加载JAVA_HOME/jre/lib/ext目录或者由系统属性java.ext.dirs指定位置中的类库。可以通过java.endorsed.dirs指定的目录中的类库也会被加载。

        应用类加载器(Application ClassLoader): 也称为系统类加载器(System ClassLoader)。

主要用于加载CLASSPATH路径下我们自己写的类,是拓展类加载器的子类。

        用户自定义类加载器:可以通过继承ClassLoader类的方式实现。允许开发者自定义类的加载方式,比如从网络、数据库或其他资源加载类。

3.2双亲委派模型

        什么是双亲委派模型?双亲委派模型(Parent Delegation Model)是Java类加载机制中的一个核心原则。这个模型规定了类加载器在加载一个类时的委托流程,确保了Java核心库的类型安全,并使得应用程序可以自定义类加载器来扩展类加载的方式。

       工作原理: 如果一个类加载器收到了类加载请求,它并不会自己先去加载,而是把这个请求委托给父类的加载器去执行,如果父类加载器还存在其父类加载器,则进一步向上委托,依次递归,请求最终将到达顶层的启动类加载器。如果父类加载器可以完成类加载任务,就成功返回。 倘若父类加载器无法完成此加载任务,子加载器才会尝试自己去加载。

总结:委托——>父类加载递归——>检测是否已加载——>自己加载——>返回结果

3.3面试题:如何打破双亲委派机制?

  1. 自定义类加载器: 创建一个自定义类加载器,并重写loadClass(String name, boolean resolve)方法。在这个方法中,类加载器可以按照自己的逻辑来加载类,而不是委托给父类加载器。

  2. 使用findClass方法: 在自定义类加载器中,重写findClass方法来实现自己的类查找和加载逻辑。如果findClass方法返回了一个类的Class对象,那么双亲委派模型就会被打破。

  3. 使用defineClass方法: 在findClass方法中,使用defineClass方法来定义类。这个方法允许类加载器将字节码转换成Class对象,而不需要委托给父类加载器。

4.调优类加载机制:

        1.优化类加载性能:优化类加载性能可以通过减少类加载次数、优化类加载路径和使用自定义类加载器来实现。例如,可以通过预热类加载器来减少运行时的类加载次数。

        2.减少类加载次数:通过分析应用程序的类加载模式,可以预先加载那些在运行时会被频繁加载的类。这可以通过在应用启动时执行一个“预热”过程来实现。

        3.优化类加载路径:确保类路径(classpath)中只包含必要的JAR文件和类文件,可以减少类加载器的搜索时间。

        4.使用自定义类加载器:自定义类加载器可以用于实现特定的类加载策略,例如按需加载类或者从特定的网络位置加载类。

        5.监控和诊断:使用工具如jVisualVM、JConsole或者Java Mission Control来监控类加载活动。这些工具可以帮助识别类加载过程中的性能瓶颈。

5.结论

        JVM的类加载机制是影响Java应用程序性能的关键因素。通过理解类加载的工作原理和调优类加载过程,开发者可以显著提升应用程序的性能。此外,合理利用类加载器和监控工具可以帮助开发者更有效地进行JVM调优。

        后续会更新JVM内存模型,有兴趣的小伙伴可以关注一波!!!

标签:Java,jvm,自定义,应用程序,调优,JVM,父类,加载
From: https://blog.csdn.net/qq_74011163/article/details/142549484

相关文章

  • 为什么要学习jvm调优?
    第一章:学习JVM调优的理由        我们为什么要学习jvm调优,学习jvm调优的好处是什么,我想大多数人都会这么想,我学这个东西来干嘛的,可以给我们带来什么好处?接下来我就来帮你好好分析一下:        1.面试:随着互联网门槛越来越高,JVM知识成为中高级程序员阶段必问......
  • uniapp - 详解安卓App打包后使用uni.chooseLocation地址列表一直加载转圈问题,Android
    前言网上的教程都无法解决问题,本文提供强力解决方案。在uni-app安卓App平台端开发中,详解uniApp打包成Android安卓后用chooseLocation打开地图选择位置空白卡住不动问题,选择地址列表什么也没有且一直处于加载状态(永远不会加载出来卡住了),另外点击搜索框后也无法搜索地点......
  • Android应用程序启动与资源加载
    Android系统中的应用程序启动与资源加载详解在Android系统中,AMS(ActivityManagerService)扮演着核心角色,负责管理应用程序的生命周期和进程调度,包括启动应用进程等关键操作。下面将详细解析AMS启动应用进程时涉及的第一个线程、代码和资源的加载过程,以及R.id.xx的加载机制......
  • Android代码调试与调优指南
    Android代码调试与调优指南在Android应用开发中,代码调试与调优不仅是确保应用稳定运行、提升用户体验的必要环节,也是开发者专业技能的重要体现。随着Android系统版本的更新和硬件设备的多样化,开发者需要掌握更加全面和深入的调试与优化技术。一、深入理解Android架构与性......
  • JVM工具-基础
    Jvm内存1.堆内存(Heap):堆内存是Java中用于存放对象实例的内存区域,几乎所有的对象实例(包括数组)都在这里分配内存。堆内存由垃圾回收器(GarbageCollector,GC)自动管理,程序员不需要手动释放。堆内存可以细分为年轻代(YoungGeneration)、老年代(OldGeneration)和永久代(PermGen,在Java8及......
  • 【Java】JVM垃圾收集器深入解析:原理与实践
    目录一、判断对象是否存活1.引用计数算法2.可达性计数算法3.Java中的四种引用 3.1强引用(StrongReference)3.2软引用(SoftReference)3.3弱引用(WeakReference)3.4虚引用(PhantomReference)3.5小结二、垃圾收集算法1.分代收集理论1.1分代存储1.2分......
  • 关于动态库加载问题
    1,GetProcAddress只能加载与函数名一致的符号,如果是C++符号是无法加载函数的所以在进行动态库加载时候,如果被加载的库是C++组件,需要将接口声明添加extern“C”或者增加def文件;否则会出现GetProcAddress加载动态函数时候失败;2,查看动态库是否有符号可以使用depend工具:http://w......
  • springboot 工程中 SpringApplication.run方法 可以指定加载"applicationContext.xml"
    在SpringBoot应用程序中,SpringApplication.run()方法默认使用自动配置和基于Java的配置(如使用@Configuration注解的类),而不是传统的XML配置文件(如applicationContext.xml)。SpringBoot的设计理念之一就是简化配置,鼓励使用注解和Java配置来代替XML配置。然而,如果你......
  • 优化Windows 10 Direct3D性能的注册表;优化Direct3D和整体游戏性能,可以从图形渲染、GPU
    优化Windows10Direct3D性能的注册表.reg文件示例CopyCodeWindowsRegistryEditorVersion5.00;优化Direct3D性能[HKEY_CURRENT_USER\Software\Microsoft\Direct3D]"DisableDirectDraw"=dword:00000001"MaxTextureWidth"=dword:00000400"MaxText......
  • Java 性能调优:调整 GC 线程以获得最佳结果
        垃圾回收(GC)在Java的内存管理中起着重要作用。它有助于回收不再使用的内存。垃圾回收器使用自己的线程集来回收内存。这些线程称为GC线程。有时,JVM最终可能会有太多或太少的GC线程。在这篇文章中,我们将讨论为什么JVM最终会拥有太多/太少的GC线程,它的后果,以及解......