当前位置: 首页 > 后端技术 > Java

JVM虚拟机(总体架构、class文件结构)我来啦~~~

时间:2023-04-01 21:04:58 Java

虚拟机1.1发展历史1.1.1Java历史Java诞生于一群懒惰、急躁、狂妄自大的编程天才中。1990年12月,Sun工程师PatrickNaughton被当时糟糕的SunC++工具逼疯了。他大声抱怨并威胁说要离开Sun去NeXT,然后在史蒂夫乔布斯的领导下。为了留住他,给他机会,领导层启动了一个名为Stealth的项目。随着JamesGosling等人的加入,该项目更名为Green。它的目标是使用C++为嵌入式设备开发一种新的底层平台技术,JamesGosling本人负责开发一个编辑器。后来有人分析,这个天才程序员太懒了,没学好C++,开发的时候撞包了。于是他决定开发一种新的编程语言。他将这种语言命名为C++++--,意思是C++“加上一些好的东西,减去一些坏的东西”。显然这个可怜的名字不能长久,所以很快这种受到同行喜爱的小语言被命名为Oak。1992年9月,Oak语言与GreenOS和一些应用程序一起在一个名为Start的小型设备上发布7、首次亮相。孙随后创办了一家名为FirstPerson的公司,整个团队都被调到这家公司开发机顶盒,以竞标时代华纳的项目。在技??术狂热的鼓舞下,这些天才开发了一种高度交互的设备。没想到时代华纳和有线电视服务商不想让用户有那么大的控制权,所以在竞标战中败给了SGI。Sun无奈关闭了FirstPerson并召回了整个团队,但java的出路并没有因此断送,因为这个的。随着互联网发展的风起云涌,java开始离开嵌入式小设备,向互联网靠拢。1994年,Oak更名Java,重回热血的IT行业,搭上互联网的大潮,从此一发不可收拾。剩下的大家都知道了...1.1.2版本迭代1991年,博士.JamesGosling发布了产品橡树(Oak),这是Java语言的前身。1995年,Oak语言更名为Java。1996年,JDK(用于Java开发的工具包)1.0发布,提供了一个纯解释执行的Java虚拟机实现:SunClassicVM。1997年,JDK1.1发布,代表技术:JDBC、JavaBeans、内部类、反射。1998年,JDK1.2发布,Java技术体系分裂为三个体系:J2SE、J2EE、J2ME。2000年,JDK1.3发布,默认的Java虚拟机由SunClassicVM改为HotSopt。2002年,JDK1.4发布,Java真正走向成熟。代表技术包括:正则表达式、NIO等。2004年JDK5.0发布,大大提高了语法的易用性,增加了泛型、枚举等,代表技术包括:并发契约等。在2006年,JDK6.0发布,J2EE/J2SE/J2ME的命名方式改为JavaSE6、JavaEE6、JavaME6。2009年,Sun因经营不善被甲骨文收购。2011年,JDK7发布。2013年,JDK8(LTS)发布,函数式编程,lamda表达式。2017年,JDK92018年,JDK10、11(LTS)正式发布2019年,JDK12、132020年,JDK14、152021年,JDK16、17(LTS)附:sun与微软Java的轶事是诞生于1995年,是微软在软件行业地位达到顶峰的时代。但这个初出茅庐的小子,恰好引起了微软帝国的注意。于是在1996年,微软向Sun申请了java认证。微软的加持,确实提升了人们对java的信心和兴趣。但好景不长。自1997年发布第一个版本的VisualJ++以来,Microsoft开始将自己的私有扩展合并到Java中。这无疑引起了孙的极大重视。1997年10月,Sun公司在加州地方法院起诉微软公司违反了两家公司签订的关于微软公司使用Java技术的合同,指控微软公司对其Java产品进行“不当修改”,违反了合同约定。承诺向用户提供与Java兼容的产品条款。诉讼一直持续到2001年1月,双方达成和解。2001年7月,微软宣布新版WindowsXP不再支持Sun的JVM,推出.NET平台与Java竞争。当然现在用.net的人少了,这是后话了。1.1.3两种jdkopenjdkvsoraclejdk:OracleJDK会更注重稳定性,更看重企业级用户,而OpenJDK经常发布支持其他特性,稳定性较差。OracleJDK支持长期版本变更(LTS),而OpenJDK只支持规划和最终确定下一个版本。OracleJDK根据二进制代码许可协议获得许可,而OpenJDK根据GPLv2许可获得许可。2019年1月之后发布的OracleJavaSE8的公共更新将不会在商业上可用,但是,OpenJDK是完全开源的并且可以免费使用。OracleJDK的构建过程是基于OpenJDK的,所以OpenJDK和OracleJDK在技术上没有区别。顶级公司都在使用OracleJDK,OpenJDK不太受欢迎。OracleJDK具有良好的GC选项和更好的渲染器,而OpenJDK具有较少的GC选项在响应性和JVM性能方面,OracleJDK提供了更好的性能。OracleJDK在运行JDK时不会产生任何问题,而OpenJDK有时会产生一些问题。OracleJDK从10.0.X版本开始收费,用户必须付费或者必须依赖OpenJDK才能使用其免费版本。OracleJDK完全由甲骨文公司开发,而OpenJDK项目则由IBM、Apple、SAPAG、Redhat等顶级公司加盟合作。1.2JVM系统JDK(JavaDevelopmentKit)是Java语言的软件开发工具包,是整个java开发的核心。它包括JRE和开发工具包JRE(Java运行时环境)。核心类库(JavaAPI)JVM(JavaVirtualMachine),Java虚拟机,它运行在操作系统之上,它与硬件没有直接交互所谓“codeonce,runanywhere”是基于不同系统的jvm帮助你掩盖系统间接口的差异:总之jdk是一个开发者的工具包,它包括java运行环境和虚拟机,一次编写到处运行是基于jvm1.3的各种虚拟机列表1.3.11.SunClassicVM世界上第一个商用Java虚拟机。1996年随着Java1.0的发布,JDK1.4被彻底淘汰2.BEAJRockit专注于服务器端应用,号称是世界上最快的JVM后来被Oracle收购;OracleJRockit(原BeaJRockit)3、IBM的J9VM全称:IBMTechnologyforJavaVirtualMachine,简称IT4J,内部代号:J9是IBM自己开发的JVM。市场定位接近HotSpot,多用途VM4,HotSpotVM(现在最常用)是SunJDK和OpenJDK中的虚拟机,也是目前使用最广泛的Java虚拟机。5.其他(TaobaoJVM,GraalVM,AzulVM,LiquidVM,ApacheHarmony,)虚拟机1.3.2见shawn@macpro:~>java-versionjavaversion"1.8.0_181"Java(TM)SERuntimeEnvironment(build1.8.0_181-b13)JavaHotSpot(TM)64-BitServerVM(build25.181-b13,mixedmode)hotspot虚拟机ClientVM专为快速启动和小内存(小占用空间)而优化,像GUI非常适合ServerVM专为高性能应用而优化。例如服务端应用版本基于tag1.8.0_1811.4jvm整体架构1.4.1java运行过程1.源码编译:通过Java源码编译器将Java代码编译成JVMBytecode(.class文件)2.Class加载:通过ClassLoader及其子类完成JVM的类加载3.类执行:字节码加载到内存,进入JVM虚拟机,由解释器解释执行1.4。2jvm模型从上图可以看出,JVM虚拟机主要由三部分组成,分别是类加载子系统、运行时数据区、执行引擎。类加载子系统Java虚拟机从Class文件中加载描述类的数据到内存中,并对数据进行校验、转换、解析和初始化,最终形成虚拟机可以直接使用的Java类型。运行时数据区Java虚拟机在Java程序执行过程中将其管理的内存划分为若干不同的数据区。这些区域都有自己的用途,以及创建和破坏的时间。有些区域随着虚拟机进程的启动而一直存在,有些区域的建立和销毁取决于用户线程的启动和结束。执行引擎执行引擎用于执行JVM字节码指令。主要有两种方式,即解释执行和编译执行。不同的是,解释执行是在执行时翻译成虚拟机指令执行,而编译执行是在执行前进行。先编译再执行。解释和执行启动快,但执行效率低。编译执行,慢启动,高效执行。垃圾收集器就是自动管理运行数据区的内存,清理无用的内存占用,释放内存资源。native方法库和native库接口在jdk的底层。有些实现需要调用本地方法(用c或c++写的方法),通过本地库接口调用完成。例如:System.currentTimeMillis()方法。2.Class文件结构要了解jvm的所有后续动作,首先要从字节码开始。它是一切发生的源头。2.1测试用例2.1.1源码包com.itheima.jvm.demo;publicclassClassStruct{privatestaticStringname="JVM";publicstaticvoidmain(String[]args){System.out.println("Hello"+name);}}2.1.2编译1)Maven定义编译版本org.apache.maven.pluginsmaven-compiler-plugin1.81.82)编译mvncleancompile2.2字节码结构2.2.1二进制概述1)打开vscode2)class文件是二进制文件,转换后以十六进制显示。实际上class文件是一个表,由以下数据项组成,从头到尾严格按照如下顺序排列:数字cp_infoconstant_poolconstant_pool_count-1体常量u2access_flags1访问标志u2this_class1类索引u2super_class1父类索引u2interfaces_count1接口索引u2interfacesinterfaces_count具体接口u2fields_count1字段个数field_infofieldsfields_count具体字段u2methods_count1方法个数method_infomethodsmethods_count具体方法u2attributes_count1属性个数attribute_infoattributesattributes_count具体属性3)图示如下:2.2.2魔数Version1)magicnumber:CAFEBABE,coffeebaby,fixed2)versionnumber:34,changingtodecimalis52jdkversiontagmappingrelationship:itmeansjdk8isusedforcompilation,wechangeitto1.6,andexecutemvncleanagaincompile,andthentrytoviewtheclassfile:org.apache.maven.pluginsmaven-compiler-plugin1.61.6Duringthedevelopmentoftheextension,youoftenencountererrorslikeUnsupportedmajor.minorversion51.0.IngeneralThefollowingareallcausedbyJDKversionmismatch.虽然jdk代码在执行过程中基本是向下兼容的,但是!开发环境和服务器环境的jdk应该是一样的,千万不要尝试这个圈套。区分理解两种环境:编译环境,运行环境2.2.3常量池遵循同样的规则:计数器(标签后面有多少)+数字对应的结构体下面以常量池为例:1)位置2)结构说明常量池在jvm中记录了一堆常量信息,由[2个字节计数]+[n个cp_info结构]组成其中cp_info有多种类型:direct类型,存放当前值,这种是引用Integer、Long等类型有一定的长度,它存储指向其他位置的指针。附:绿色代表指针,橙色代表直接类型3)Case下面以String为例。String是一个引用类。它会指向一个utf8类型来存储真实的信息。JDK提供了一个工具,javap,可以查看常量列表的详细信息:javap-vClassStruct.class2.2.4其他信息1)常量池之后,旁边有一系列信息,信息类似,仅此而已thanavalue,orareference(参考上面2.3.3中的表格和图例)accessmark:publicabstract等信息类索引,类类型,最后指向一个utf8,标记当前类父类的名字,同上Interface,2字节记录的个数,后面是多个接口类型,后面是字段,方法,属性,就是2字节记录的个数,后面是对应的结构类型2)了解javap后的注意事项如果你了解这些格式,你就可以很容易地理解类结构类型标识符大小写描述数组[[Ljava.案例说明类中的属性、字段、方法等com.test.Demo.name:Ljava.lang.String以点号分隔,标识什么类型com.test.Demo.getName:()Ljava.lang.String以点号分隔冒号打开方法(参数类型)返回值类型英文括号,后面是返回值类型3)实例分析如果本文对您有帮助,请关注点赞`,您的支持是我坚持创作的动力。转载请注明出处!