JAVA虚拟机工作原理_第1页
JAVA虚拟机工作原理_第2页
JAVA虚拟机工作原理_第3页
JAVA虚拟机工作原理_第4页
JAVA虚拟机工作原理_第5页
已阅读5页,还剩30页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

淘宝技术大学应届生培训

JVM工作原理课程组:雷卷

小邪

九穆版本:第一版2009年达到的目标知道Java虚拟机的生存周期知道JVM的体系结构知道JVM体系结构中的各个部分能对JVM有个大致清晰的了解内容JVM的生命周期JVM的体系结构JVM类加载器JVM执行引擎JVM运行时数据区JVM垃圾回收问题JVM的生命周期

一、首先分析两个概念JVM实例和JVM执行引擎实例(1)JVM实例对应了一个独立运行的java程序

它是进程级别(2)JVM执行引擎实例则对应了属于用户运行程序的线程它是线程级别的JVM的生命周期

二、JVM的生命周期

(1)JVM实例的诞生当启动一个Java程序时,一个JVM实例就产生了,任何一个拥有publicstaticvoidmain(String[]args)函数的class都可以作为JVM实例运行的起点

(2)JVM实例的运行

main()作为该程序初始线程的起点,任何其他线程均由该线程启动。JVM内部有两种线程:守护线程和非守护线程,main()属于非守护线程,守护线程通常由JVM自己使用,java程序也可以标明自己创建的线程是守护线程。

(3)JVM实例的消亡当程序中的所有非守护线程都终止时,JVM才退出;若安全管理器允许,程序也可以使用Runtime类或者System.exit()来退出。

内容JVM的生命周期JVM的体系结构JVM类加载器JVM执行引擎JVM运行时数据区JVM垃圾回收问题JVM的体系结构

JVM的体系结构一、

JVM的内部体系结构分为三部分,(1)类装载器(ClassLoader)子系统作用:用来装载.class文件

(2)执行引擎

作用:执行字节码,或者执行本地方法

(3)运行时数据区方法区,堆,java栈,PC寄存器,本地方法栈

内容JVM的生命周期JVM的体系结构JVM类加载器JVM执行引擎JVM运行时数据区JVM垃圾回收问题JVM的体系结构之类加载器一、

JVM将整个类加载过程划分为了三个步骤:(1)装载

装载过程负责找到二进制字节码并加载至JVM中,JVM通过类名、类所在的包名通过ClassLoader来完成类的加载,同样,也采用以上三个元素来标识一个被加载了的类:类名+包名+ClassLoader实例ID。(2)链接链接过程负责对二进制字节码的格式进行校验、初始化装载类中的静态变量以及解析类中调用的接口、类。在完成了校验后,JVM初始化类中的静态变量,并将其值赋为默认值。最后一步为对类中的所有属性、方法进行验证,以确保其需要调用的属性、方法存在,以及具备应的权限(例如public、private域权限等),会造成NoSuchMethodError、NoSuchFieldError等错误信息。(3)初始化初始化过程即为执行类中的静态初始化代码、构造器代码以及静态属性的初始化,在四种情况下初始化过程会被触发执行:调用了new;反射调用了类中的方法;子类调用了初始化;JVM启动过程中指定的初始化类。JVM的体系结构构之类加载载器JVM的体系结构构之类加载载器一、JVM两种类装载载器包括::启动类装装载器和用用户自定义义类装载器器,启动类类装载器是JVM实现的一部部分,用户户自定义类类装载器则则是Java程序的一部部分,必须须是ClassLoader类的子类。。二、主要要分为以下下几类:(1)BootstrapClassLoader这是JVM的根ClassLoader,它是用C++实现的,JVM启动时初始始化此ClassLoader,并由此ClassLoader完成$JAVA_HOME中jre/lib/rt.jar(SunJDK的实现)中中所有class文件的加载载,这个jar中包含了java规范定义的的所有接口口以及实现现。(2)ExtensionClassLoaderJVM用此classloader来加载扩展展功能的一一些jar包(3)SystemClassLoaderJVM用此classloader来加载启动动参数中指指定的Classpath中的jar包以及目录录,在SunJDK中ClassLoader对应的类名名为AppClassLoader。(4)User-DefinedClassLoaderUser-DefinedClassLoader是Java开发人员继继承ClassLoader抽象类自行行实现的ClassLoader,基于自定定义的ClassLoader可用于加载载非Classpath中的jar以及目录JVM的体系结构构之类加载载器三、ClassLoader抽象类提供供了几个关关键的方法法:(1)loadClass此方法负责责加载指定定名字的类类,ClassLoader的实现方法法为先从已已经加载的的类中寻找找,如没有有则继续从从parentClassLoader中寻找,如如仍然没找找到,则从从SystemClassLoader中寻找,最最后再调用用findClass方法来寻找找,如要改改变类的加加载顺序,,则可覆盖盖此方法(2)findLoadedClass此方法负责责从当前ClassLoader实例对象的的缓存中寻寻找已加载载的类,调调用的为native的方法。(3)findClass此方法直接接抛出ClassNotFoundException,因此需要要通过覆盖盖loadClass或此方法来来以自定义义的方式加加载相应的的类。(4)findSystemClass此方法负责责从SystemClassLoader中寻找类,,如未找到到,则继续续从BootstrapClassLoader中寻找,如如仍然为找找到,则返返回null。(5)defineClass此方法负责责将二进制制的字节码码转换为Class对象(6)resolveClass此方法负责责完成Class对象的链接接,如已链链接过,则则会直接返返回。JVM的体系结构构之类加载载器四、简单的的classLoader例子/**重写ClassLoader类的findClass方法,将一一个字节数数组转换为为Class类的实例*/publicClass<?>findClass(Stringname)throwsClassNotFoundException{byte[]b=null;try{b=loadClassData(AutoClassLoader.FormatClassName(name));}catch(Exceptione){e.printStackTrace();}returndefineClass(name,b,0,b.length);}/**将指定定路径的.class文件转换成成字节数组组*/privatebyte[]loadClassData(Stringfilepath)throwsException{intn=0;BufferedInputStreambr=newBufferedInputStream(newFileInputStream(newFile(filepath)));ByteArrayOutputStreambos=newByteArrayOutputStream();while((n=br.read())!=-1){bos.write(n);}br.close();returnbos.toByteArray();}JVM的体系结构构之类加载载器四、简单的的classLoader例子/**格式化化文件所对对应的路径径*/publicstaticStringFormatClassName(Stringname){FILEPATH=DEAFAULTDIR+name+".class";returnFILEPATH;}/**main方法测试*/publicstaticvoidmain(String[]args)throwsException{AutoClassLoaderacl=newAutoClassLoader();Classc=acl.findClass("testClass");Objectobj=c.newInstance();Methodm=c.getMethod("getName",newClass[]{String.class,int.class});m.invoke(obj,"你好",123);System.out.println(c.getName());System.out.println(c.getClassLoader());System.out.println(c.getClassLoader().getParent());}内容JVM的生命周期期JVM的体系结构构JVM类加载器JVM执行引擎JVM运行时数据据区JVM垃圾回收问题JVM的体系结构构之执行引引擎一、JVM通过执行引引擎来完成成字节码的的执行,在在执行过程程中JVM采用的是自自己的一套套指令系统统,每个线程在在创建后,,都会产生生一个程序序计数器((pc)和栈(Stack),其中程程序计数器器中存放了了下一条将将要执行的的指令,Stack中存放StackFrame,表示的为为当前正在在执行的方方法,每个个方法的执执行都会产产生StackFrame,StackFrame中存放了传传递给方法法的参数、、方法内的的局部变量量以及操作作数栈,操操作数栈用用于存放指指令运算的的中间结果果,指令负负责从操作作数栈中弹弹出参与运运算的操作作数,指令令执行完毕毕后再将计计算结果压压回到操作作数栈,当当方法执行行完毕后则则从Stack中弹出,继继续其他方方法的执行行。在执行方法法时JVM提供了invokestatic、invokevirtual、invokeinterface和invokespecial四种指令来来执行(1)invokestatic:调用类的的static方法(2)invokevirtual:调用对对象实例的的方法(3)invokeinterface:将属性定定义为接口口来进行调调用(4)invokespecial:JVM对于初始化化对象(Java构造器的方方法为:<init>)以及调用用对象实例例中的私有有方法时。。JVM的体系结构构之执行引引擎二、反射机机制是Java的亮点之一一,基于反反射可动态态调用某对对象实例中中对应的方方法、访问问查看对象象的属性等等,而无需需在编写代代码时就确确定需要创创建的对象象,这使得得Java可以实现很很灵活的实实现对象的的调用,代代码示例如如下:ClassactionClass=Class.forName(外部实现类类);Methodmethod=actionClass.getMethod(““execute””,null);Objectaction=actionClass.newInstance();method.invoke(action,null);反射的关键键:要实现现动态的调调用,最明明显的方法法就是动态态的生成字字节码,加加载到JVM中并执行JVM的体系结构构之执行引引擎(1)ClassactionClass=Class.forName(外部实现类类);调用本地方方法,使用用调用者所所在的ClassLoader来加载创建建出Class对象;(2)Methodmethod=actionClass.getMethod(““execute””,null);校验此Class是否为public类型的,以以确定类的的执行权限限,如不是是public类型的,则则直接抛出出SecurityException;调用privateGetDeclaredMethods来获取到此此Class中所有的方方法,在privateGetDeclaredMethods对此Class中所有的方方法的集合合做了缓存存,在第一一次时会调调用本地方方法去获取取;扫描方法集集合列表中中是否有相相同方法名名以及参数数类型的方方法,如有有则复制生生成一个新新的Method对象返回;;如没有则继继续扫描父父类、父接接口中是否否有此方法法,如仍然然没找到方方法则抛出出NoSuchMethodException;JVM的体系结构构之执行引引擎(3)Objectaction=actionClass.newInstance();第一步:校校验此Class是否为public类型,如权权限不足则则直接抛出出SecurityException;第二步:如如没有缓存存的构造器器对象,则则调用本地地方法获取取到构造器器,并复制制生成一个个新的构造造器对象,,放入缓存存,如没有有空构造器器则抛出InstantiationException;第三步:校校验构造器器对象的权权限;第四步:执执行构造器器对象的newInstance方法;构造造器对象的的newInstance方法判断是是否有缓存存的ConstructorAccessor对象,如果果没有则调调用生成新的ConstructorAccessor对象;第五步:判断是否需需要调用本本地代码,,可通过sun.reflect.noInflation=true来设置为不不调用本地地代码,在在不调用本本地代码的的情况下,,就转交给给MethodAccessorGenerator来处理了;;第六步:MethodAccessorGenerator中的generate方法根据JavaClass格式规范生生成字节码码,字节码码中包括了了ConstructorAccessor对象需要的的newInstance方法,此newInstance方法对应的的指令为invokespecial,所需的参参数则从外外部压入,,生成的Constructor类的名字以以:sun/reflect/GeneratedSerializationConstructorAccessor或sun/reflect/GeneratedConstructorAccessor开头,后面面跟随一个个累计创建建的对象的的次数;第七步:在在生成了字字节码后将将其加载到到当前的ClassLoader中,并实例例化,完成成ConstructorAccessor对象的创建建过程,并并将此对象象放入构造造器对象的的缓存中;;最后一步::执行获取取的constructorAccessor.newInstance,这步和标标准的方法法调用没有有任何区别别。JVM的体系结构构之执行引引擎(4)method.invoke(action,null);这步执行的的过程和上上一步基本本类似,只只是在生成成字节码时时生成的方方法改为了了invoke,其调用的的目标改为为了传入的的对象的方方法,同时时生成的类类名改为了了:sun/reflect/GeneratedMethodAccessor。注:但是getMethod是非常耗性性能的,一一方面是权权限的校验验,另外一一方面所有有方法的扫扫描以及Method对象的复制制,因此在在使用反射射调用多的的系统中应应缓存getMethod返回的Method对象JVM的体系结构构之执行引引擎2、执行技术术主要的执行行技术有:解释,即时时编译,自自适应优化化、芯片级级直接执行行(1)解释属于于第一代JVM,(2)即时编译译JIT属于第二代代JVM,(3)自适应优优化(目前前Sun的HotspotJVM采用这种技技术)则吸吸取第一代代JVM和第二代JVM的经验,采采用两者结结合的方式式(4)自适应优优化:开始始对所有的的代码都采采取解释执执行的方式式,并监视视代码执行行情况,然然后对那些些经常调用用的方法启启动一个后后台线程,,将其编译译为本地代代码,并进进行仔细优优化。若方方法不再频频繁使用,,则取消编编译过的代代码,仍对对其进行解解释执行。。内容JVM的生命周期期JVM的体系结构构JVM类加载器JVM执行引擎JVM运行时数据据区JVM垃圾回收问题JVM的体系结构构之运行时时数据区一、JVM在运行时将将数据划分分为了6个区域来存存储,而不不仅仅是大大家熟知的的Heap区域,这6个区域图示示如下:JVM的体系结构构之运行时时数据区第一块:PC寄存器PC寄存器是用用于存储每每个线程下下一步将执执行的JVM指令,如该该方法为native的,则PC寄存器中不不存储任何何信息。第二块:JVM栈JVM栈是线程私私有的,每每个线程创创建的同时时都会创建建JVM栈,JVM栈中存放的的为当前线线程中局部部基本类型型的变量((java中定义的八八种基本类类型:boolean、char、byte、short、int、long、float、double)、部分的的返回结果果以及StackFrame,非基本类类型的对象象在JVM栈上仅存放放一个指向向堆上的地地址第三块:堆堆(Heap)Heap是大家最为为熟悉的区区域,它是是JVM用来存储对对象实例以以及数组值值的区域,,可以认为为Java中所有通过过new创建的对象象的内存都都在此分配配,Heap中的对象的的内存需要要等待GC进行回收。。JVM的体系结构构之运行时时数据区JVM将Heap分为NewGeneration和OldGeneration(或TenuredGeneration)两块来进行管理::(1)NewGeneration又称为新生生代,程序序中新建的的对象都将将分配到新新生代中,,新生代又又由EdenSpace和两块SurvivorSpace构成,可通通过-Xmn参数来指定定其大小(2)OldGeneration又称为旧生生代,用于于存放程序序中经过几几次垃圾回回收还存活活的对象,,例如缓存存的对象等等,旧生代代所占用的的内存大小小即为-Xmx指定定的的大大小小减减去去-Xmn指定定的的大大小小。。JVM的体体系系结结构构之之运运行行时时数数据据区区对堆堆的的解解释释::(1)堆堆是是JVM中所所有有线线程程共共享享的的,,因因此此在在其其上上进进行行对对象象内内存存的的分分配配均均需需要要进进行行加加锁锁,,这这也也导导致致了了new对象象的的开开销销是是比比较较大大的的(2)鉴鉴于于上上面面的的原原因因,,SunHotspotJVM为了了提提升升对对象象内内存存分分配配的的效效率率,,对对于于所所创创建建的的线线程程都都会会分分配配一一块块独独立立的的空空间间,,这这块块空空间间又又称称为为TLAB(ThreadLocalAllocationBuffer),,其其大大小小由由JVM根据据运运行行的的情情况况计计算算而而得得,,在在TLAB上分分配配对对象象时时不不需需要要加加锁锁,,因因此此JVM在给给线线程程的的对对象象分分配配内内存存时时会会尽尽量量的的在在TLAB上分分配配,,在在这这种种情情况况下下JVM中分分配配对对象象内内存存的的性性能能和和C基本本是是一一样样高高效效的的,,但但如如果果对对象象过过大大的的话话则则仍仍然然是是直直接接使使用用堆堆空空间间分分配配(3)TLAB仅作作用用于于新新生生代代的的EdenSpace,因因此此在在编编写写Java程序序时时,,通通常常多多个个小小的的对对象象比比大大的的对对象象分分配配起起来来更更加加高高效效,,但这这种种方方法法同同时时也也带带来来了了两两个个问问题题,,一一是是空空间间的的浪浪费费,,二二是是对对象象内内存存的的回回收收上上仍仍然然没没法法做做到到像像Stack那么么高高效效,,同同时时也也会会增增加加回回收收时时的的资资源源的的消消耗耗,,可可通通过过在在启启动动参参数数上上增增加加-XX:+PrintTLAB来查查看看TLAB这块块的的使使用用情情况况。。JVM的体体系系结结构构之之运运行行时时数数据据区区第四四块块::方方法法区区域域((MethodArea)(1)方方法法区区域域存存放放了了所所加加载载的的类类的的信信息息((名名称称、、修修饰饰符符等等))、、类类中中的的静静态态变变量量、、类类中中定定义义为为final类型型的的常常量量、、类类中中的的Field信息息、、类类中中的的方方法法信信息息,,当当开开发发人人员员在在程程序序中中通通过过Class对象象中中的的getName、isInterface等方方法法来来获获取取信信息息时时,,这这些些数数据据都都来来源源于于方方法法区区域域,,可可见见方方法法区区域域的的重重要要性性,,同同样样,,方方法法区区域域也也是是全全局局共共享享的的,,在在一一定定的的条条件件下下它它也也会会被被GC,当当方方法法区区域域需需要要使使用用的的内内存存超超过过其其允允许许的的大大小小时时,,会会抛抛出出OutOfMemory的错误信信息。(2)在SunJDK中这块区区域对应应的为PermanetGeneration,又称为为持久代,默认为为64M,可通过过-XX:PermSize以及-XX:MaxPermSize来指定其其大小。。第五块::运行时时常量池池(RuntimeConstantPool)类似C中的符号号表,存存放的为为类中的的固定的的常量信信息、方方法和Field的引用信信息等,,其空间间从方法法区域中中分配。。第六块::本地方方法堆栈栈(NativeMethodStacks)JVM采用本地地方法堆堆栈来支支持native方法的执执行,此此区域用用于存储储每个native方法调用用的状态态。内容JVM的生命周周期JVM的体系结结构JVM类加载器器JVM执行引擎擎JVM运行时数数据区JVM垃圾回收收问题JVM的体系结结构之内内存回收收一、JVM中自动的的对象内内存回收收机制称称为:GC(GarbageCollection)1、GC的基本原原理:为将内存存中不再再被使用用的对象象进行回回收,GC中用于回回收内存存中不被被使用的的对象的的方法称称为收集集器,由由于GC需要消耗耗一些资资源和时时间的,,Java在对对象象的生命命周期特特征进行行分析后后,在V1.2以上的版版本采用用了分代代的方式式来进行行对象的的收集,,即按照照新生代代、旧生生代的方方式来对对对象进进行收集集,以尽尽可能的的缩短GC对应用造造成的暂暂停(1)对新生生代的对对象的收收集称为为minorGC,(2)对旧生生代的对对象的收收集称为为FullGC,(3)程序中中主动调调用System.gc()强制执行行的GC为FullGC,JVM的体系结结构之内内存回收收二、JVM中自动内内存回收收机制(1)引用计计数收集集器原理:引用计数数是标识识Heap中对象状状态最明明显的一一种方法法,引用用计数的的方法简简单来说说就是对对每一个个对象都都提供一一个关联联的引用用计数,,以此来来标识该该对象是是否被使使用,当当这个计计数为零零时,说说明这个个对象已已经不再再被使用用了。优点:引用计数数的好处处是可以以不用暂暂停应用用,当计计数变为为零时,,即可将将此对象象的内存存空间回回收,但但它需要要给每个个对象附附加一个个关联引引用计数数缺点:并且引用用计数

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论