jvm - 初步了解JVM体系结构 & 类装载器 & 双亲委派机制和沙箱安全

JVM的体系结构图:(橙色+灰色)
灰色:线程私有(即每个线程对应一个)、内存占的特别少,几乎不存在垃圾回收

Execution执行引擎:解释命令,交由操作系统执行
本地方法接口:设计的目的就是融合不同的语言为Java所用。(本地方法接口在本地方法栈中登记标记为native的方法,当执行引擎执行时,本地方法接口调用native方法库)(即本地方法接口是本地方法栈、执行引擎、本地方法库的中心)

 

方法区不是放方法的区,是放类的描述信息,即放模板的地方。

类装载器不唯一,有几种,类不同,类装载器也可能不同。类加载器分类如下:
考点一:分为两大类(即红字):

1、虚拟机自带的类加载器
(你可以在jre/lib/rt.jar中找到Object.class、ArrayList.class、String.class等Java最基础的、自带的类,这也是为什么你一装好jdk,就能使用这些类的原因,这些类由启动类加载器(Bootstrap Class Loader负责加载并初始化(目的是加载.class,得到Class,放进方法区中)(但类加载器负责加载并初始化,并不负责实例化)))
(而jre/lib/ext中的jar则是在jdk1.0以后引入的,javax中的"x"指的就是ext的意思,javax.包下的类就是在jdk1.0以后引入的新类,由扩展类加载器(Extension)负责)
(用户自己写的类由应用程序类加载器(AppClassLoader负责加载))

2、用户自定义的类加载器
即自己写一个类加载器,需要继承自ClassLoader父类

 

(从图看出,第一大类的三个具体类,从上到下的关系为爷爷-爸爸-儿子)(从下面的举例代码中的输出结果也可以看出这个结论(getParent()方法))

先用一个demo,解释一下加载器的第一大类:虚拟机自带的类加载器
Object类,是系统自带的
MyObject类,是程序员自己写的

运行结果:
前两个报空指针异常 NPE
第三个为null

后三个为:

(启动类加载器(Bootstrap Class Loader)在Java中的输出为null,所以这个的null就是在表达像Object这种在jdk1.0就写好了的类,是由启动类加载器加载的)
(用户自定义加载器并不加载用户自定义的类!!用户自定义的类的.class文件由应用程序类加载器(AppClassLoader)加载)

再解释一下第二大类:用户自定义加载器
这个就厉害了,比如如果你嫌Oracle公司写的类加载器不够好,你可以通过继承抽象类ClassLoader的方式,自己写一个满足自己要求的类加载器:

 


双亲委派机制:
在类加载器加载并初始化类的时候,先在启动类加载器(Bootstrap)对应的查找范围中的类中去找,没找到再去扩展类加载器,再去应用程序类加载器中找。
所以双亲委派机制的目的是保证程序员自己写的类不能污染Java提供的类,保证沙箱安全(防止恶意代码去污染Java提供的源代码)(如程序员自己在包java.lang下新建一个String类,肯定会出问题,保证大家加载的类都是同一个),说白了,这个机制的目的是保证安全性。
即coder自己写了个String类,并且指定了由APP类加载器加载,但因为在不考虑自定义类加载器的前提下,首先会在AppClassLoader中检查是否加载过,如果有那就无需再加载了。如果没有,那么会拿到父加载器,然后调用父加载器的loadClass方法。父类中同理会先检查自己是否已经加载过,如果没有再往上到达启动类加载器。如果最顶层加载器都无法加载,会下沉到子加载器去加载,一直到最底层,如果没有任何加载器能加载,就会抛出ClassNotFoundException。
无论你想伪造什么样的系统提供的类,从最终都会向上委托到Extension甚至是Bootstrap类加载器那里,发现已经加载过该类了(这时你想伪造的类就不会被加载),此时即使篡改了就也不会加载,就保证了安全性

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

 


类装载器负责将Student.class 加载并初始化,变成 Student Class(它就是Student的模板,放进了方法区里)。(类装载器并不负责实例化)
实例化的时候就根据方法区里Student的模板,实例化出三个student实例,它们都属于Student类,因为它们三个来自同一个模板(通过student1.getClass()(得到大Class,即反射)、student2.getClass()两者结果一样,可以验证出来)。

 


执行引擎不负责执行命令

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值