| |
|
开发:
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(一) |
java平台无关性平台无关性是一种语言在计算机上的运行不受平台约束,一次编译,到处执行。 java语言的规范,Class文件,JVM在java的平台无关性扮演着重要的角色。 java语言规范java的基本数据类型的值域和行为都是由自己定义的。而C++的基本数据类型的占位宽度是由所在平台决定的。 对于int类型,在java中,int占4个字节,是固定的。在C++中,在16位的计算集中,int类型的长度 占2个字节,32位计算机上占4个字节,在64位计算机上,int类型的长度可能占8字节。 class字节码文件java在不同平台的虚拟机都使用统一的字节码格式,java虚拟机只与由自己组成的Class文件进行交互。jvm会自行判断加载的class文件是否符合虚拟机的规范。 java虚拟机在不同的硬件和操作系统上,主要的区别就是指令不同。jvm根据对应的硬件和操作系统生成对应的二进制指令。 ?JVM类加载系统类加载机制java虚拟机把描述类的数据从Class文件加载到内存,经过验证、准备、解析、初始化后,最终形成可以被java虚拟机直接使用的java类型的过程。 类加载时机加载、验证、准备、初始化、卸载这五个阶段顺序是按部就班的“开始”的,开始强调的是这些步骤可能也是交叉进行的。比如说解析阶段可能会在初始化后面(解析阶段和验证、准备都包含在链接阶段)。为了支持java语言的运行时绑定特性。(多态,编译看左边,运行看右边) JVM规范对类加载过程的第一阶段“加载”没有强制性约束,对于初始化阶段严格规定了有且仅有六种情况必须立即进行初始化(主动引用) 1.遇到new、getStatic、putStatic、invokestatic这四个指令时 2.使用java.lang.reflect包下的方法进行反射调用时 3.子类初始化的时候,如果父类还没有初始化,应该先初始化父类 4.JVM启动的时候,JVM会先初始化main()所在的类 5.默认接口的实现类初始化的时候,该接口应该在实现类之前初始化 6.使用jdk动态语言支持的时候,java.lang.invoke.MethodHandle实例解析结果为REF_getStatic,REF_putStatic,REF_invokeStatic,REF_newInvokeSpecial四种类型的方法句柄,这些句柄对应的类还没有进行初始化 被动引用不会出发初始化 1.通过子类引用父类的静态字段,只会触发父类进行初始化,不会引起子类初始化 2.定义的数组引用类,不会触发此类初始化 3.一个类调用另一个类的静态常量时,不会引起另一个类的初始化,因为在编译期,将静态常量已经放入了常量池 类加载过程1.加载阶段 目的:通过一个类的全限定名获取此类二进制字节流,存入到方法区中,生成的class对象,作为外部访问方法区的入口 获取字节流的途径:java源码编译生成的class文件,ZIP压缩包中读取,网络获取等 2.链接阶段 ①验证 验证主要是为了确保class文件的字节流中包含的信息符合虚拟机的规范,保证加载类的正确性,不会危害虚拟机的安全 验证方式: 文件格式验证:验证字节流是否符合class文件格式的规范。例:是否以魔数开头、主次版本号是否在当前JVM接受的范围内 元数据验证:对字节码描述的信息进行语义分析,对元数据信息中的数据类型校验。例:是否继承Object类 字节码验证:数据流及控制流进行语义分析,确定程序的语义适合法的,符合逻辑的。例:不相关类的强制转换 符号引用验证:解析阶段,将符号引用转换为直接引用的时候发生 ②准备 对类中定义的变量分配空间和设置类变量的初始值,一般为数据类型的0值,如果是静态常量(final),在准备阶段就设置为定义的值,类变量会分配在方法区,实例变量分配在堆中 ③解析 将常量池中符号引用转换为直接引用的过程 解析操作一般在JVM完成初始化之后进行 符号引用:一组用来描述所引用的目标的符号 直接引用:直接指向目标的指针、相对偏移量或一个间接定位到目标的句柄 3.初始化 执行类构造器<clinit>(),此方法是javac编译器自动收集类中的所有类变量的赋值动作和静态代码块中语句合并而来的。 ①编译器收集类中的类变量和静态代码块的顺序是按照源文件中出现的先后顺序进行的 ②JVM会先保证父类的<clinit>()方法执行,然后在执行子类的 ③如果类中没有类变量或者静态代码块,可以不生成<clinit>() ④JVM必须保证<clinit>()在多线程下被同步加锁 双亲委派模型?对于任意一个类,都必须由加载他的类加载器和这个类本身一起确定他在JVM中的唯一性 例如:比较两个类是否相等,只有在这两个类是由同一个类加载器加载的前提下比较才有意义,就算两个类来源于同一个class文件,但是他们是由不同的类加载器加载,这两个类就一定不相同 启动类加载器由c/c++实现,是虚拟机自身的一部分,加载java核心类库到虚拟机内存(java中获取加载器类型时,如果返回null,代表该加载器是启动类加载器) 扩展类加载器加载JAVA_HOME/jre/lib/ext目录下或者从java.ext.dirs系统指定目录中加载类库允许用户将自定义的jar放置在此目录下,都有扩展类加载器加载 应用程序加载器负责加载环境变量classpath或系统属性java.class.path指定路径下的类库,该类加载器为程序中默认的类加载器 自定义加载器继承classloader,并重写findclass()方法指定字节码获取方式,loadClass模板方法会调用findClass 双亲委派模型一个类加载器收到类加载请求,先检查请求加载的类是否被加载过,如果没有,他会将这个请求发送给父类,依次向上发送,直到发送给启动类加载器,如果启动类加载器可以完成加载任务,则成功返回,如果无法完成任务,就交给子类加载器,如果有加载器可以完成,子加载器调用自己的findClass()进行加载 |
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2025年1日历 | -2025/1/29 7:28:21- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |