资源描述
,*,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,单击此处编辑母版标题样式,单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,*,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,单击此处编辑母版标题样式,*,单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,*,java,虚拟机原理介绍,1,目录,Java,虚拟机,1.java,虚拟机的生命周期,2.java,虚拟机的体系结构,Java class,文件,1.magic(,魔数,),2.minor_version,和,major_version,3.constant_pool_count,和,constant_pool,2,类型的生命周期,1.,类型的装载、连接和初始化,2.,对象的生命周期,3.,卸载类型,连接模型,动态连接和解析,垃圾收集,3,Java,虚拟机生命周期,4,每运行一个,java,程序,便得到,JAVA,虚拟机的实例,每个,Java,程序都运行于它自己的,Java,虚拟机实例中,当程序关闭退出,这个虚拟机实例也就随之消亡,程序本身也能够通过调用,Runtime,类或者,System,类的,exit(),方法退出。,5,Java,虚拟机体系结构,6,在,Java,假虚拟机规范中,一个虚拟机实例的行为时分别按照子系统、内存区、数据类型以及指令这几个术语来描述的。这些组成部分一起展示了抽象的虚拟机的内部抽象体系结构。,7,8,1,)所有的线程都共享方法区,方法区必须被设计为线程安全的,方法区大小不固定,2,)方法区 存储以下类型信息:,类的全限定名,超类的全限定名,是接口还是类,类的访问修饰修饰符,该类的,【,常量池,】,字段信息,方法信息,类(静态)变量:类变量是由所有类实例共享的,即使没有类实例,也可以访问,一个到类,ClassLoader,引用,一个到类的引用,3),方法表,运行时数据区,-,方法区,9,堆,1,)同一个,java,应用所有的线程共享堆空间(由于每一个,java,程序独占一个,java,虚拟机实例,因面每个,java,程序都有它自己的堆空间),堆空间可以分为三部分:一个,Eden,区,,Survivor,区和,truned,区,2,)由,new,操作符创建的对象均位于堆中,运行时数据区,java,中的堆,10,运行时数据区,-Java,中的栈,每启动一个新的线程,,java,虚拟机都会为它分配一个,java,栈,,java,栈上的都是此线程私有的,每当启用一个线程时,,JVM,就为他分配一个,Java,栈,栈是以帧为单位保存当前线程的运行状态。,【,当前方法,当前帧,当前类,当前常量池,】,每当线程调用一个,Java,方法时,,JVM,就会在该线程对应的栈中压入一个帧,这个帧自然就成了当前帧。当执行这个方法时,它使用这个帧来存储参数、局部变量、中间运算结果等等。,Java,栈上的所有数据都是私有的。任何线程都不能访问另一个线程的栈数据。,Java,栈和帧在内存中也不必是连续的,帧可以分布在连续的栈里,也可以分布在堆里,11,栈帧,栈帧由三部分组成:局部变量区、操作数栈和帧数据区,12,Java,的,class,文件,13,Class,文件的内容,在,class,文件中,可变长度项的大小和长度位于其实际数据之前,这个特性使得,class,文件数据流可以被顺序解析,首先读出项的大小,然后读出项数据,1.magic,(魔数),4,个字节,2.minor_version,和,major_version 4,个字节,3.constant_pool_count,和,constant_pool,4.access_flags 2,个字节,5.this_class 2,个字节,14,6.super_class 2,个字节,7.interfaces_count,和,interfaces,8.fields_count,和,fields,9.methods_count,和,fields,10.attributes_count,和,attributes,15,Java,代码编译和执行的整个过程包含了以下三个重要的机制:,1.Java,源码编译机制,2.,类加载机制,3.,类执行机制,Java,代码编译是由,Java,源码编译器来完成,流程图如下所示:,16,Java,字节码的执行是由,JVM,执行引擎来完成,流程图如下所示:,17,class,文件由以下部分组成:,1.,结构信息,包括,class,文件格式版本号及各部分的数量与大小的信息,2.,元数据,对应于,Java,源码中声明与常量的信息。包含类,/,继承的超类,/,实现的接口的声明信息、域与方法声明信息和常量池,3.,方法信息,。,对应,Java,源码中语句和表达式对应的信息。包含字节码、异常处理器表、求值栈与局部变量区大小、求值栈的类型记录、调试符号信息,18,Java,中的类加载机制,19,Java,中的类加载机制,JVM,的类加载是通过,ClassLoader,及其子类来完成的,类的层次关系和加载顺序可以由下图来描述:,20,21,Bootstrap ClassLoader/,启动类加载器,$JAVA_HOME,中,jre/lib/rt.jar,里所有的,class,,由,C+,实现,不是,ClassLoader,子类,Extension ClassLoader/,扩展类加载器,负责加载,java,平台中扩展功能的一些,jar,包,包括,$JAVA_HOME,中,jre/lib/*.jar,或,-Djava.ext.dirs,指定目录下的,jar,包,App ClassLoader/,系统类加载器,负责加载,classpath,中指定的,jar,包及目录中,class,Custom ClassLoader/,用户自定义类加载器,(java.lang.ClassLoader,的子类,),属于应用程序根据自身需要自定义的,ClassLoader,,如,tomcat,、,jboss,都会根据,j2ee,规范自行实现,ClassLoader,22,Java,中的类加载双亲委派机制,JVM,在加载类时默认采用的是,【,双亲委派,机制,】,。通俗的讲,就是某个特定的类加载器在接到加载类的请求时,首先将加载任务委托给父类加载器,依次递归,如果父类加载器可以完成类加载任务,就成功返回;只有父类加载器无法完成此加载任务时,才自己去加载。,23,java,中的类执行机制,JVM,是基于栈的体系结构来执行,class,字节码的。线程创建后,都会产生程序计数器(,PC,)和栈(,Stack,),程序计数器存放下一条要执行的指令在方法内的偏移量,栈中存放一个个栈帧,每个栈帧对应着每个方法的每次调用,而栈帧又是有局部变量区和操作数栈两部分组成,局部变量区用于存放方法中的局部变量和参数,操作数栈中用于存放方法执行过程中产生的中间结果。,24,java,类的生命周期,25,装载:就是把二进制形式的,java,类型读入,java,虚拟机中,验证:,准备:为类变量分配内存,设置默认值。但是在到达初始化,之前,类变量都没有初始化为真正的初始值,解析:解析过程就是在类型的常量池中寻找类、接口、字段,和方法的符号引用,把这些符号引用替换成直接引用,的过程在符号引用被程序首次使用之前,连接这个步骤,都是可选的,初始化,:,为类变量赋予正确的初始值,类实例化,:,为新的对象分配内存,为实例变量赋默认值,为实例变量赋正确的初始值,java,编译 器为它编译的每一个类都至少生成一个实例初始化,方法,在,java,的,class,文件中,这个实例初始化方法被称为,”,“,。针对源代码中每一个类的构造方法,,java,编译器都,产生一个,方法,26,JVM,内存回收,27,JVM,内存回收,根集,(root set),:,所谓根集就是正在执行的,Java,程序可以访问的引用变量的集合,(,包括局部变量、参数、类变量,),,程序可以使用引用变量访问对象的属性和调用对象的方法。垃圾收集首选需要确定从根开始哪些是可达的和哪些是不可达的,从根集可达的对象都是活动对象,它们不能作为垃圾被回收,这也包括从根集间接可达的对象。而根集通过任意路径不可达的对象符合垃圾收集的条件,应该被回收,28,常用的算法:,1,、引用计数法,(Reference Counting ollector),2,、,tracing,算法,(Tracing Collector),3,、,compacting,算法,(Compacting Collector),4,、,copying,算法,(Coping Collector),5,、,generation,算法,(Generational Collector),6,、,adaptive,算法,(Adaptive Collector),29,Sun,的,JVMGenerationalCollecting,算法,Sun,的,JVMGenerationalCollecting(,垃圾回收,),原理是这样的:把对象分为年青代,(Young),、年老代,(Tenured),、持久代,(Perm),,对不同生命周期的对象使用不同的算法。,(,基于对对象生命周期分析,),30,31,1.Young,(年轻代),年轻代分三个区。一个,Eden,区,两个,Survivor,区。大部分对象在,Eden,区中生成。当,Eden,区满时,还存活的对象将被复制到,Survivor,区(两个中的一个),当这个,Survivor,区满时,此区的存活对象将被复制到另外一个,Survivor,区,当这个,Survivor,去也满了的时候,从第一个,Survivor,区复制过来的并且此时还存活的对象,将被复制年老区,(Tenured,。需要注意,,Survivor,的两个区是对称的,没先后关系,所以同一个区中可能同时存在从,Eden,复制过来对象,和从前一个,Survivor,复制过来的对象,而复制到年老区的只有从第一个,Survivor,去过来的对象。而且,,Survivor,区总有一个是空的。,2.Tenured,(年老代),年老代存放从年轻代存活的对象。一般来说年老代存放的都是生命期较长的对象。,3.Perm,(持久代),用于存放静态文件,如今,Java,类、方法等。持久代对垃圾回收没有显著影响,但是有些应用可能动态生成或者调用一些,class,,,32,所讲内容尽供参考,,如有错误码,敬请更正,33,
展开阅读全文