白话JVM(一)整体介绍

提到JVM,先从大致上分为三个部分,即类加载子系统,内存区域,字节码执行引擎。先来说类加载子系统。
类加载子系统的作用就是把java文件翻译成字节码文件,再加载到内存区域中去,且如果不使用则不加载,使用时才加载,所谓的使用是指main和new这两个关键字。其过程分为5个步骤,即加载,检查,准备,解析,初始化。其中,加载是指从硬盘中找到.java文件,将其翻译成二进制字节码文件。检查是指检查.class文件是否被修改,是否符合jvm指令的词法,语法。我打开过.class文件,发现里面都是4个组成的字符,他是能被JVM识别的,甚至可以去查各个字符的语义,他是有词法语法的,不能被篡改的,检查这一步骤就是为了防止其被篡改。之后是准备,即给静态变量分配内存,并赋默认值,如int类型赋值0。boolean类型赋值false,引用类型赋值null。再然后是解析,将文件引用替换成内存地址引用或句柄,就是将人去取的名字替换成具体的内存地址,方便JVM进行读取。最后是初始化,即有的静态变量是被赋值过的,在这一步会将原来的默认值覆盖掉。
上面是具体的加载过程,再来谈一谈宏观点的加载过程,即双亲委派机制。想弄清双亲委派就必须先弄清楚有哪几个类加载器。类加载器分为三类,启动类加载器,他用来加载jar下的lib目录下的核心类库。还有扩展类加载器,用来加载jre下的ext扩展目录下的类。再然后是应用程序类加载器。具体看ClassLoader代码会发现,其主要方法有两个,一个是findClass,跑出异常,目的是给子程序重写。一个是loadClass,里面实现了双亲委派的逻辑,即应用程序加载类时,先判断这个类是否已经被加载过,被加载过则直接使用,没加载过就去找父类进行加载,当到最顶层ClassLoader,没有父类时,会调用native方法findBootStrapClassLoader去加载类。
这就是双亲委派机制,它的好处是沙箱安全,保护了jre中核心类不被篡改,比如我们自己写一个java.lang.String,在这个机制下,这个类是不会被类加载器加载的,最终调用的还是jre中的String。还有一个好处是保证类的唯一性,不会被重复加载,因为源码loadClass中关于双亲委派那一段逻辑有一个if,用来判断是否已经加载过了,所以不会重复加载。
双亲委派机制优势会被打破,比如tomcat这个web容器,他的一些需求导致他需要打破双亲委派,比如,一个大的tomcat下的两个应用程序,依赖同一个第三方类库的不同版本,若还双亲,则导致无法区分两个版本,且其中一个失效。再比如,多个应用程序之间依赖需要隔离,有的又需要共享,还有就是tomcat自身的依赖类库需要和应用程序隔离。这些需求决定了tomcat不再适合双亲委派机制。他怎么打破双亲委派机制呢?通过自定义类加载器,重写findClass,更重要的是重写了loadClass方法,修改了loadClass方法中的双亲委派逻辑,将类加载在自己这里完成。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值