| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> Java知识库 -> 深入理解jvm - 类加载过程 -> 正文阅读 |
|
[Java知识库]深入理解jvm - 类加载过程 |
前言? 在最早的文章中,我们虽然讨论过了类加载器的过程,但是并没有讲述内部的细节,本文将会根据类加载器的过程,详细说一下整个类加载的过程中每一个步骤都干什么事情。 ? 类加载的过程如下:加载,验证,准备,初始化,解析,使用,卸载。重点需要关注的步骤是前面的五个步骤,这些细节算是八股文的内容,所以这篇文章以简单的总结和归纳为主。 概述? 本篇主要讲述类加载的加载过程,在类加载的过程当中包含了前五个步骤和详细的细节。 类加载的过程? 下们拆分这五个步骤,讲讲每一个步骤都做了哪些事情: 加载? 第一步是加载,加载做的事情就是什么时候jvm需要去找到.class这个对象,我们都知道.class对象如果方法区中存在的话,java是不会去加载第二次的,那么类什么时候会进行初始化呢? ? 我们最容易想到的就是new的时候,所以可以肯定在new的时候会作为触发条件。接着我们有时候使用 ? 除了 ? 我们从继承和实现两个角度去考虑什么时候会加载,从继承的角度看,如果父类没有被加载,那么父类也是要被加载进来的,至于为什么必须使用父类,这个问题类构造器可以作为解答,我们都知道在构造器的方法会执行一条 ? 最后我们再来看下由于jdk版本带来的改进。首先是jdk7动态语言的支持,所有涉及 ? 下面我们总结上面关于加载的“初始化”条件:
最后,看一下书中给的一段加载“初始化”的代码,结果有点出乎意料哦:
? 下面再看下如果只调用子类的静态方法会发生什么事情:
验证? 验证是紧接着类加载之后的步骤,验证主要的做的事情是验证当前的class文件是否可以被虚拟机接受,这一步是至关重要的一步,决定了虚拟机是否安全,所以虚拟机规范里面用了N多页的内容讲述,当然这里的验证内容也是挑重点介绍。: ? 首先是验证文件格式,比如魔数,主次版本,常量池和索引,验证这些内容目的是防止有人篡改class文件结构。 ? 验证完格式紧接着是验证具体的数据,比如类是否具备父类,以及验证定义的字段和属性等是否符合java的语法。这一节也叫做元数据验证,可以简单理解为对于语法等验证。 ? 之后是字节码验证,也是最复杂的步骤,因为程序的运行依赖程序计数器扫描字节码指令完成,所以字节码验证主要的内容就是验证操作的“原子性”,比如Int操作不会变为long操作,同时保证栈帧的方法正常运行。 ? 最后是符号引用的验证,验证是否能通过符号引用找到类的全限定名称,验证字段是否具备可访问性等。 ? 总的来说,验证阶段分为下面等部分:
准备? 容易误解的一个阶段,这个阶段需要注意的事情就是准备阶段初始化的静态变量是 final类型的静态常量。另外准备阶段会对类变量进行初始化,但是不会出现类的实例化,也就是说此时生成的仅仅是一个栈中的引用,可以通过引用在初始化阶段快速构建对象但是仅仅是做了一个准备而已,另外需要注意由于jdk7其实内部已经偷偷将常量池移动到了堆当中,所以这些变量都是在堆中生成的。 ? 下面是关于静态变量的初始化细节:
? 这里直接说结果,count在这个阶段的值是123,而count2是0。通过这个细节也可以说明为什么很多书中建议尽量使用final字段,因为它能将“初始化”的步骤提前。积少成多的情况下有不错的性能提升。 解析? 解析的核心就是把符号引用变为直接引用,什么是符号引用,什么是直接引用呢?书中用了一大段内容描述,这里用一个案例来表示就明白了(请看下面的代码),obj就可以被认为是一个符号引用,符号引用可以是任何没有歧义的“占位符”(当然和关键字冲突是不行的),而直接引用就是将这个占位符指向一个堆中的实例,有了直接引用也证明实例在内存中已经开辟了空间,所以直接引用一定是一个指针并指向堆中一个实际地址:
? 解析动作主要针对类或接口、字段、类方法、接口方法、方法类型、方法句柄和调用点限定符这7 类符号引用进行。 ? 关于解析的细节,这里简要概括一下,当然这部分只需要了解四个主要步骤即可:
初始化? 注意这个步骤才是程序员真正认知意义上的初始化,也就是学习java基础的时候学到的初始化的顺序,同时也是真正执行java代码的阶段,所以这个阶段用“分配资源”这个词可能更加合适。 ? 之前也提到过,准备阶段会有一个类变量的构建,可以认为是.class对象被加载到方法区,而初始化则是真正将方法区的这个引用构建到堆上。 ? 这里不得不提 类加载的细节? 了解了类加载的过程,这一节来补充一些类加载的细节: 类加载基本条件
什么是被动引用?
本文主要围绕了类加载的过程这一个要点进行了复习,可以看到类加载的过程还是相对比较好理解的,需要特别关注的内容一个是准备阶段和初始化阶段,这里也有可能是一个踩坑点。 ?最后对于程序员来说,要学习的知识内容、技术有太多太多,要想不被环境淘汰就只有不断提升自己,从来都是我们去适应环境,而不是环境来适应我们! 不用多说,相信大家都有一个共识:无论什么行业,最牛逼的人肯定是站在金字塔端的人。所以,想做一个牛逼的程序员,那么就要让自己站的更高,成为技术大牛并不是一朝一夕的事情,需要时间的沉淀和技术的积累。 现在竞争这么激烈,只有通过不断学习,提高自己,才能保持竞争力。 对于一些不知道学习什么,没有一个系统路线的程序员,这里给大家提供一些学习资料
《Java核心知识点合集(283页)》内容涵盖:Java基础、JVM、高并发、多线程、分布式、设计模式、Spring全家桶、Java、MyBatis、ZooKeeper、Dubbo、Elasticsearch、Memcached、MongoDB、Redis、MySQL、RabbitMQ、Kafka、Linux、Netty、Tomcat、数据库、云计算等 《Java中高级核心知识点合集(524页)》《Java高级架构知识点整理》《Docker从入门到实践》《spring could 学习笔记》《JVM与性能调优知识点整理》《MySQL性能调优与架构设计解析文档》305页《Nginx入门到实战》319页《Java并发编程》385页《1000道 互联网Java工程师面试题 (485页)》
|
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/23 9:40:45- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |