栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

类的加载过程、自定义加载器、JVM执行模式设置

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

类的加载过程、自定义加载器、JVM执行模式设置

文章目录
    • CLASS 加载过程
      • Loading
        • 类加载器
          • 双亲委派
        • 自定义类加载器
      • linking
        • Verification
        • Preparation
        • Resolution
      • initializing
    • JVM执行模式
      • 解释模式
      • 编译模式
      • 混合模式
      • 调优参数

CLASS 加载过程

Loading

首先,类加载器通过类的全路径限定名称读取类的二进制字符流(获取二进制字符流)
其次,将字节流代表的静态存储结构化为方法去的运行时数据(结构化静态数据)
最后, 在堆生成一个代表这个类的class实例(不是这个类的实例)(在内存中生成class对象)

类加载器


启动类加载器/Bootstrap ClassLoader:负责加载JAVA_HOME/lib目录中的所有类
拓展类加载器/ExtClasLoader:负责加载 JAVA_HOME/lib/ext目录中的所有类
应用程序类加载器/AppClassLoader:负责加载用户类路径ClassPath下的所有类型

双亲委派

过程:当jvm收到类的加载请求时,会首先查询上一级加载器是否加载过这个类,若加载过,直接由上一级加载器返回结果,直到最顶层的bootstrap classloader。若都没有加载过,由最顶层开始判断是否可以加载这个类,如果加载器加载目录下找不到这个类,则会交给下一级加载器去加载
我们看下源码

首先会判断是否被当前加载器加载了,加载了则返回;如果没有则会判断当前加载器是否有上级加载器,交由上级加载器加载。
优点:可以防止类的污染,一个类只会去被加载一次。
(历史上有4次java打破了双亲委派机制的事件,感兴趣的百度看看)

自定义类加载器

优点: 可以加载指定目录下的class文件。
可以参考一下下面这篇文章
https://www.jianshu.com/p/7ee1bfe63216
实现:
新建一个类继承自java.lang.ClassLoader,重写它的findClass方法。
将class字节码数组转换为Class类的实例
调用loadClass方法即可

public class MyClassLoader extends ClassLoader{

    @Override
    protected Class findClass(String name) throws ClassNotFoundException {
        File f = new File("C:/.../.../"+name.replaceAll("\.","/").concat(".class"));
        try {
            FileInputStream fis = new FileInputStream(f);
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            int b = 0;
            //数据写进字节数组
            while ((b=fis.read())!=0){

                byteArrayOutputStream.write(b);
            }

            byte[] bytes = byteArrayOutputStream.toByteArray();
            byteArrayOutputStream.close();
            fis.close();
            return  defineClass("name",bytes,0,bytes.length);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return super.findClass(name);
    }
}
		ClassLoader loader = new MyClassLoader();
        Class clazz = loader.loadClass("com.....class全称");
        Object o = clazz.newInstance();
linking Verification

验证是连接阶段的第一步,这一阶段的目的是确保Class文件的字节流中包含的信息符合《Java虚拟机规范》的全部约束要求。 验证阶段大致分为四个阶段的动作,文件格式校验,元数据验证,字节码验证,符号引用验证
借张验证阶段的图:
原文在https://blog.csdn.net/weixin_43893397/article/details/121611635

Preparation

准备阶段是给静态变量分配内存并 设置类变量初始值 的阶段。

Resolution

解析阶段是Java虚拟机将常量池内的符号引用替换为直接引用的过程。
符号引用(Symbolic References):符号引用以一组符号来描述所引用的目标,符号可以是任何形式的字面量,只要使用时能无歧义地定位到目标即可。
直接引用(Direct References):直接引用是可以直接指向目标的指针、相对偏移量或者是一个能间接定位到目标的句柄。

initializing

这个阶段才真正开始执行java代码,静态代码块和设置变量的初始值为程序员设定的值

JVM执行模式

解释模式

解释执行:通过解释器将源语言代码逐条解释成机器语言,然后提交给计算机执行,解释一条执行一条,不形成目标程序,不依赖于平台
缺点:解析需要时间,不生成目标程序,而是一句一句的执行的方式会造成计算机资源的浪费,即执行效率低。

编译模式

编译执行:由编译器将目标代码一次性全部编译成目标程序,再由机器运行目标程序。相比解释执行编译执行效率高,占用资源小,适合复杂程序。

混合模式

JVM默认的执行方式为混合模式 ,混合使用解释器和热点代码编译(JIT JUST IN TIME COMPILER),对于多次被调用的方法(方法计数器:检测方法执行频率)或者多次被调用的循环(循环计数器:检测循环执行频率)进行编译执行。
检测热点代码 XX:CompileThreshold = 1000…

调优参数

-Xmixed 默认混合模式
-Xint 使用解释模式 ,启动很快,执行略慢
-Xcomp 使用纯编译模式,执行很快,启动很慢
在idea当中里参数加一下就行

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/685533.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号