jdk-虚拟机

jdk-虚拟机

从java.exe 开始讲投java类加载运行全过程

jdk远吗级别剖析jvm核心类加载器

jdk源码级别剖析类加载双亲委派机制

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

tomcat了加载机制深度剖析

手写tomcat类加载器实现多个版本代码共存隔离

 classLoad.loadClass(.class) ==> 类 如果加载在虚拟机上的

 

验证 字节码文件是否正确,有规范

javap  -v  Math.class  ,下面就是 二进制的另外一种现实方式,更容易查看

 准备: 

静态变量 赋予初始值,,注意是变量,如果是常量是直接赋值的

解析:

关于符号引用转为直接引用(符号到内存地址的转换)

静态链接:比如静态方法

动态链接:运行时,才去解析,比如多态,只有运行时候才知道调用哪个方法

 main 在类加载阶段,符号转为直接引用

math.compute() 符号是在常量池里,在运行阶段 回去解析,将符号解析为直接引用

java -p 一下:   解释下动态链接math.compute()   

 

class 文件的   invokevirtual #4   对应就是java 文件的math.compute()  

 

 

 这些字节码文件都是静态的,符号也都是静态的

代码加载到jvm内存中之后 就放到方法区,这些方法在内存中就会有地址,一旦这些符号加载到jvm内存,这些常量池就会变成运行时常量池,都有内存地址指向 ,math.compute 只有在main方式执行的时候才会去解析 math.compute这个符号,根据这个符号去到内存找对应的内存位置找到compute方法。

 static 方法是不变的,在类加载的时候 就直接将符号转为地址

 方法区,Class对象放到堆里面


类加载器

 

单例创建 Laucher ,获取得到ext类加载器和ap类加载器,都是类对象,每个类加载器都有一个parent,即父类加载器(除了根类加载器,c++写的)

 

 

 

 源码对应路径:打印 app类加载器加载类的文件夹,包含根和扩展类加载器下的文件下 ,类都是交给应用类加载器,然后不能加载的通过双亲委派:

 

双亲委派:

 1、判断是否已经加载过得,底部是通过 private native final Class<?> findLoadedClass0(String name); 的一个native方法。AppClassLoader 加载java.lang.String 通过该方法可直接判断已被加载过,那么就直接返回,无需调用父加载器(非父类,不是继承关系)

 

 自己写个java.lang.String  

首先交给appClassloader,没有加载过,交个ext  最后交给root  ,因为根类加载器加载lib包,string是没有main这个方法,因此抛出错误。

自定义类加载器的父加载器是应用类加载器,因此自定义加载器会先交给应用类加载器加载

 自定义类加载器的步骤:

1:继承ClassLoader

2:实现finClass方法

defineClass native方法,传递二进制字节码文件进去

 

 在D盘的test文件夹下放置:

 打破双亲委派

重写父类的 java.lang.ClassLoader#loadClass(java.lang.String, boolean)  方法

 删除双亲委派的逻辑,报错:

 Object类是所有类的父了,然后自定义类加载器加载User对象的时候,也会用这个类加载器去加载Object对象,指定的classPath D://test 下没有这个class文件,所以报错

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值