JVM-类加载机制深度解析

  作者:图灵javaer


在线预览


类加载过程


  • 加载:在硬盘上查找并通过IO读入字节码文件,使用到类时才会加载


补充:使用到类时才会加载这个是针对用户写的类,而支撑jvm运行的一些类比如java.lang包下的类是启动的时候就已经加载到jvm中


  • 验证:校验字节码文件的正确性

比如以下字节码文件:



如果手动修改这个字节码文件,则校验会报错



  • 准备:给类的静态变量分配内存,并赋予默认值




其中initData变量的默认值为0


  • 解析:将符号引用替换为直接引用


该阶段会把一些静态方法(符号引用,比如main()方法)替换为指向数据所存内存的指针或句柄


  • 初始化:对类的静态变量初始化为指定的值,执行静态代码块



在准备阶段已经将initData变量赋值默认值0,初始化则是将initData变量赋值为代码中所写的666变量值


类加载器


  • 应用程序类加载器:负责加载ClassPath路径下的类包,主要就是加载你自己写的那些类



双亲委派机制


双亲委派机制说简单点就是,先找父亲加载,不行再由儿子自己加载


查看源码:发现如果有父类ClassLoader那么就会调用父类ClassLoader的loadClass






为什么要设计双亲委派机制?


  • 沙箱安全机制:自己写的java.lang.String.class类不会被加载,这样便可以防止核心API库被随意篡改
  • 避免类的重复加载:当父亲已经加载了该类时,就没有必要子ClassLoader再加载一次,保证被加载类的唯一性



Tomcat打破双亲委派机制


1、比如tomcat下有两个应用程序,一个用spring4版本的,另一个用spring5版本的,那么两个应用程序的spring肯定是由很多类名是一样的,那么就需要隔离两个应用程序,打破双亲委派的机制

2、比如像servlet.jar这样的公用的jar包,如果有10个应用程序部署,那么它们将使用同一份同版本的servlet.jar,打破双亲委派机制

3、比如tomcat下有两个应用程序,一个有自己的一个依赖jar包,另一个不希望有这个依赖包,打破双亲委派机制


自定义类加载器打破双亲委派机制


需要去掉双亲委派相关代码




沙箱安全机制


在自定义类加载器路径中添加java.lang.String类






则会抛出包名禁止异常


相关推荐

评论 抢沙发

表情

分类选择