01-017 jvm类加载器、双亲委派与沙箱安全

ClassLoader

负责加载class文件,class文件在文件开头有特定的文件标示(cafe babe,后面符合Java的语法规定),将class文件字节码内容加载到内存中,并将这些内容转换成方法区中运行时数据结构并且ClassLoader只负责class文件加载,置于它是否可以运行,则由Execution Engine决定
在这里插入图片描述
ps.大Class装进方法区,一个类的模板,按照模板生成实例N个

类装载器有几个,一般来说3个(重点)
虚拟机自带的加载器:

  1. 启动类加载器(Bootstrap)C++
  2. 扩展类加载器(Extension)Java
  3. 应用程序类加载器(AppClassLoader)
  4. 用户自定义加载器 Java.lang.ClassLoader的子类,可以定制类的加载方式
public class MyObject {
    public static void main(String[] args) {
    	// jre/lib/rt.jar中有Object.class  启动类加载器直接加载
        Object object = new Object();
        System.out.println(object.getClass().getClassLoader().getParent().getParent());
        //NullPointerException
        System.out.println(object.getClass().getClassLoader().getParent());
        //NullPointerException
        System.out.println(object.getClass().getClassLoader());
        //null 启动类加载器(Bootstrap)C++

		// javax  随着发展而后扩展的 /jre/lib/ext/下   

        MyObject myObject = new MyObject();
        System.out.println(myObject.getClass().getClassLoader());
        //sun.misc.Launcher$AppClassLoader@18b4aac2 
        //sun.misc.Launcher  jvm调用的入口程序
        
		System.out.println(myObject.getClass().getClassLoader().getParent().getParent());
		//null
		
        System.out.println(myObject.getClass().getClassLoader().getParent());
		//sun.misc.Launcher$ExtClassLoader@1b6d3586
        
    }
}

双亲委派

当一个类收到了类的加载请求,它首先不会尝试自己去加载这个类,而是把这个请求委派给父类去完成,每一个层次类加载器都是如此,因此所有的加载请求都应该传送到启动类加载其中,只有当父类加载器反馈自己无法完成这个请求的时候(在它的加载路径下没有找到所需加载的class),子类加载器才会尝试自己去加载。
采用双亲委派的一个好处是比如加载位于rt.jar包中的类java.lang.Object,不管是哪个加载器加载这个类,最终都是委托给顶层的启动类加载器进行加载,这样就保证了使用不同的类加载器最终得到的都是同一个Object对象。
双亲委派可以防止源代码污染,保证了java源代码的安全性。
在这里插入图片描述

沙箱安全机制

沙箱安全机制是由基于双亲委派机制上,采取的一种JVM的自我保护机制,假设自己写一个java.lang.String 的类,在类中自定义方法,由于双亲委派机制的原理,此请求会先交给Bootstrap试图进行加载,但是Bootstrap在加载类时首先通过包和类名查找rt.jar中有没有该类,有则优先加载rt.jar包中的类,没有自定义方法会报错,因此就保证了java的运行机制不会被破坏。

学习整理于jvm2019.

发布了53 篇原创文章 · 获赞 0 · 访问量 378

猜你喜欢

转载自blog.csdn.net/weixin_40778497/article/details/104029547