前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >JVM学习三

JVM学习三

作者头像
路行的亚洲
发布2020-07-16 21:44:12
3160
发布2020-07-16 21:44:12
举报
文章被收录于专栏:后端技术学习

1.类文件结构

通常一个java文件,编译之后会变成字节码文件。根据jvm规范,类文件的结构如下:

代码语言:javascript
复制

classFile{   
            u4 magic; #魔数,表示其是否是类文件,0-3字节,ca fe ba be   
            u2 minor_version; #版本,4-7字节,类的版本,其中34表示java8    
            u2 major_version; #主版本,   
            u2 constant_pool_count; #常量池,8-9字节,量池长度  
            cp_info constant_pool[constant_pool_count-1]; #常量池信息 
            u2 access_flags; #访问标记
            u2 super_class; #父类信息   
            u2 interfaces_count;#接口信息    
            u2 interfaces[interfaces_count];    
            u2 fields_count; #字段信息,成员变量信息    
            field_info fileds[fields_count];    
            u2 methodsCount; #方法信息    
            method_info methods[methoos_count];    
            u2 attributes_count; #属性信息    
            attribute_info attributes[attributes_count];
       }    

2.编译javap

通过javap工具,我么可以反编译class文件,从而看到java的字节码信息:

代码语言:javascript
复制
javap -v xxx.class

从字节码文件中,我们可以看到类的文件的相关信息,版本信息、字段、常量池信息、属性信息、方法信息,继承信息和标识信息等。

通常原始java代码,编译后变成字节码文件,常量信息,会放入常量池中,运行时放入到运行时常量池中。而运行常量池类似hash表,在里面可以看到里面的常量的信息。方法字节码载入方法区,main线程开始运行,分配栈帧内存。而栈帧的数据结构是栈,先进后出的特点。接着执行引擎完成字节码操作。

在编译过程期间,会自动生成和转换一些代码,方便运行。

3.类加载阶段

加载

将类的字节码载入方法区中,内部采用C++的instanceKlass描述java类,相关字段:

代码语言:javascript
复制
_java_mirror #java的类镜像,方便java使用
_super #父类
_fields #成员变量
_methods #方法
_constants #常量池
_class_loader #类加载器
_vtable #虚方法表
_itable #接口方法表

如果这个类还有父类没有加载,先加载父类。同时加载和链接可以交替运行的。

链接
代码语言:javascript
复制
链接的过程中,需要进行验证、准备、解析工作。
其中:   验证时验证类是否符合jvm规范,安全性检查   准备是为static变量分配空间,设置默认值
   将常量池中的符号引用解析为直接引用
初始化

<cinit>() v 方法,初始化即调用<cinit>() v,虚拟机会保证这个类的构造方法的线程安全。

发生的时机:类的初始化时惰性的。main方法所在的类总会被首先初始化,首次访问这个方法的静态变量或静态方法,子类初始化,如果父类还没有初始化,则会子类访问父类的静态变量,触发父类的初始化。class.forName,new会导致初始化等。

不会触发初始化的情况:

访问static final静态常量、访问类对象的.class、创建该类的数组等。

4.类加载器

代码语言:javascript
复制
Bootstrap ClassLoader:加载java_home的lib信息
Extension ClassLoader:加载java_home中的lib/ext中的信息
Application ClassLoader:加载应用的classpath的信息
自定义类加载器:自定义路径的信息

上面的四种类加载器存在上下级关系。同时从源码里面会看到其涉及双亲委派模式。

双亲委派模式:调用类加载器的loadClass方法时,查找类的规则。

查看此类是否已经加载,有上级的话,委派上级ExtClassLoader的loadClass,如果没有上级,则委派BootstrapClassLoader。如果每一层找不到,则找自定义类加载器加载。

什么时候我们会用到自定义类加载器:

代码语言:javascript
复制
1.想加载非classpath随意路径中的类文件
2.都是通过接口来使用实现,希望解耦时,常用在框架设计
3.这些类希望予以隔离,不同应用的同名类都可以加载,不冲突,常见于tomcat容器中
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-03-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 后端技术学习 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.类文件结构
  • 2.编译javap
  • 3.类加载阶段
    • 加载
      • 链接
        • 初始化
        • 4.类加载器
        相关产品与服务
        容器服务
        腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档