Java的JVM学习、类加载器(一)

JVM是什么?

JVM(Java Virtual Machine,Java虚拟机):java程序首先需要通过javac来编译,生成.class文件,然后通过java.exe(windows上)去运行,实际上java.exe是会去装载jvm.dll不同平台下是不一样的(linux下的libjvm.dll)。

jvm是jre的一部分,他是一个虚构出来的计算机,拥有自己完善的硬件架构,如处理器、堆栈、寄存器等。
更多关于JVM的概念介绍:百度百科

JVM结构

JVM内部大概分为三个部分,分别是类装载器(ClassLoader)子系统,运行时数据区(Runtime Data Area)、和执行引擎(ExecutionEngine):
JVM结构图

类装载器(ClassLoader)子系统

其主要作用是将class文件进行装载,然后可以得到该类的类类型,然后类类型的实例化就是新建每个新的对象,但是他们的信息都是与模板一样:如下图
类加载器
类加载器出去用户自定义有三种:

    1. BootStrap:启动类加载器,C++编写的,java的根基 rt.jar (Runtime)
    1. Extension:扩展类加载器 Java 用于java扩展的 jar
    1. AppClassLoader:应用程序类加载器,也叫系统类加载器,加载当前应用的classpath的所有类
      参考代码,查看结果:
public class MyObjectDemo01 {
    public static void main(String[] args) {
        Object object = new Object();
        // System.out.println(object.getClass().getClassLoader().getParent().getParent());
        // System.out.println(object.getClass().getClassLoader().getParent());
        // 这是属于java自己的类,是使用BootStrap加载器进行加载的,所以上面两个写出时会报空指针异常找不到其父类  null
        System.out.println(object.getClass().getClassLoader());

        MyObjectDemo01 myObjectDemo01 = new MyObjectDemo01();

        //  null
        System.out.println(myObjectDemo01.getClass().getClassLoader().getParent().getParent());
        // sun.misc.Launcher$ExtClassLoader@3a71f4dd
        System.out.println(myObjectDemo01.getClass().getClassLoader().getParent());
        // sun.misc.Launcher$AppClassLoader@18b4aac2 自己定义的类,走的是AppClassLoader加载器
        // sun.misc.Launcher JVM的入口程序
        System.out.println(myObjectDemo01.getClass().getClassLoader());
    }
}
null
null
sun.misc.Launcher$ExtClassLoader@3a71f4dd
sun.misc.Launcher$AppClassLoader@18b4aac2

首先是自己的类,会通过AppClassLoader进行类加载,但不是第一次就是通过该加载器加载,后面会讲为什么。而BootStrap是使用c写的,所以打印的时候会是null。

双亲委派

首先参考一段代码:

public class String {
    public static void main(String[] args) {
        /**
         * 错误: 在类 java.lang.String 中找不到 main 方法, 请将 main 方法定义为:
         *    public static void main(String[] args)
         * 否则 JavaFX 应用程序类必须扩展javafx.application.Application
         */
        System.out.println("我是自己定义的类...");

    }
}

我这里的包名:package java.lang;这样情况如果java不存在一个类似于安全校验的东西,那么下一个使用String类的对象就不知道改使用哪个,所以引出双亲委派沙箱安全

当一个类接收到了类加载器请求,该发出请求的类加载器不会自己先去尝试加载这个类,而是将这个请求委派给父类去完成,所以,所有的加载请求都会传送到启动类加载器(BootStrap)进行加载,如果父类反馈自己无法完成此次加载(就是在其加载路径下没有找到对应的class文件),子类加载器才会去尝试自己加载。
这样做的好处就是,不管是使用什么类加载器去加载String,都会先通过父加载器(Bootstrap)进行加载,这样能保证最后加载到的String对象是同一个对象.
沙箱安全:JVM将不同的代码放在不同的域中,从而控制权限

谢谢大家阅读!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值