JVM-类加载机制

类生命周期

从类加载到初始化

1、加载:读取class文件二进制字节码内容(加载到方法区)

2、验证:class文件格式规范、语义分析、引用验证、字节码验证

3、准备:分配内存、设置类static修饰的变量初始值

4、解析:类信息、类、接口、方法、字段等解析

5、初始化:为静态变量赋值、执行静态代码块

6、使用:创建实例对象

7、卸载:从JVM方法区中卸载

方法区:

JVM用来存储加载的类信息、常量、静态变量、编译后的代码的数据。

虚拟机规范中这是一个逻辑区划,具体实现根据不同虚拟机来实现,如:oracle的HotSpot在Java7中方法区放在永久代,Java8放在元素据空间,并且通过GC机制对这个区域进行管理

类如何加载到方法区?

通过类加载器:加载网络、jar、Zip、文件夹、二进制数据、内存等指定位置的类资源

运行一个程序,至少3个类加载器实例,负责不同类的加载:

1、Bootstrap loader(核心类库加载器):C/C++实现,加载JDK核心类库(lib目录、rt.jar、java.lang.String ...)

2、Extension class loader(扩展类库加载器):扩展类库(ext目录)

3、Application class loader(用户应用程序类加载器):加载java.class.path指定的目录、用户应用程序classpath

查看类对应的加载器:

通过jdk-api:java.lang.class.getClassLoader(),该方法返回装载类的类加载器

如果该类(如:String类)是由Bootstrap loader加载器加载的,则改方法返回null,因为Bootstrap loader加载器是C/C++实现,负责加载Java程序运行的必备类库

JVM如何知道我们的类在哪里?

通过java.class.path配置指定去哪些目录加载类资源

验证过程:利用jps、jcmd两个命令

jps:查看正在运行的JVM

jcmd:让正在运行中的jvm执行指令

e.g:jcmd 进程号 VM.system_properties

AppClassLoader默认读取java.class.path位置的类

URL jarUrl = new URL("file:\\D:\\demo.jar");
URLClassLoader classLoader = new URLClassLoader(new URL[]{jarUrl});

类重复加载判断:类加载器实例id+类路径+类名

tomcat类热加载原理:当文件有变化,创建一个新的类加载器实例重新加载(类路径+类名一般不会变)

查看类加载、卸载日志的JVM运行参数:--verbose:class

类卸载:

条件:

1、该class所有的实例都已被GC

2、加载该类的classloader实例被GC了

双亲委派模型:

URL jarUrl = new URL("file:\\D:\\demo.jar");
URLClassLoader classLoader1 = new URLClassLoader(new URL[]{jarUrl});

URLClassLoader classLoader2 = new URLClassLoader(new URL[]{jarUrl}, classLoader1 );

为了避免重复加载,由下到上逐级委托,由上到下逐级查找

首先不会自己去尝试加载类,而是把这个请求逐层委派给父加载器去完成

只有当父加载器反馈自己无法完成该加载请求(该加载器的搜索范围中没有找到对应的类)时,子加载器才会尝试自己去加载

注:类加载器之间不存在父类之类的关系,只是逻辑上定义的上下级关系

总结:

1、JVM知识分多个层级,知晓-领悟-熟练运用

2、当知识点被梳理清晰之后,学习方向会更加明确

3、合适的学习方法,能节约大量时间

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值