课程深入理解JAVA虚拟机2013-12-27caizi12@126.com内容大纲•分享的目标一、分享目标•Jvm相关概述•Jvm运行流程•Jvm体系架构•Jvm内存模型•JVM内存监控二、Jvm基础知识及内存设置、监控•Jvm垃圾回收机制•如何提高Eclipse的运行效率三、Jvm垃圾回收机制及性能调优实战1、分享目标能更深入的认识JAVA及JAVA虚拟机了解JAVA虚拟机的体系结构及垃圾回收机制了解JAVA虚拟机监控工具,可以进行简单的性能调优一起学习,共同成长…….2、Jvm基础知识及内存设置、监控2.1、JVM相关概念1、什么是JVM2、JVM能运行哪些编程语言3、JVM运行流程4、JVM生命周期5、三大流行的JVM2.2、JVM体系结构1、类加载器2、执行引擎3、运行时数据区4、本地库接口2.3、JVM内存参数调整及监控1、JVM之内存调整2、JVM监控工具之Jconsole3、JVM监控工具之JProfile什么是JAVA虚拟机JVM是JAVA虚拟机(JAVAVirtualMachine)的缩写,是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。JAVA虚拟机有自己完善的虚拟硬件架构,如处理器、堆栈、寄存器等,还具有相应的指令系统。JVM屏蔽了与具体操作系统平台相关的信息,使得JAVA程序只需生成在JAVA虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改地运行JVM能运行哪些编程语言JVMJPythonJAVAScalaCeylon………CloiureGroovyJRubyJVM可以运行任何能编译成符合JVM字节码规范的字节码。JAVA和其他JVM语言都是要经过编译成字节码之后运行的。一次编写,到处运行。经过多年的发展JVM已经成为一个多元化的平台,越来越多的语言可以运行在JVM上。JVM运行流程JAVA源程序JAVA字节码(.class文件)编译通过本地或网络传输字节码JAVA虚拟机Windows下的JAVA字节码解释程序Linux下的JAVA字节码解释程序能直接解释JAVA字节码的CPUWindows操作系统Linux操作系统本地机器指令本地机器指令等…本地机器指令JVM的生命周期(1)JVM实例的诞生当启动一个JAVA程序时,一个JVM实例就产生了,任何一个拥有publicstaticvoidmain(String[]args)函数的class都可以作为JVM实例运行的起点(2)JVM实例的运行main()作为该程序初始线程的起点,任何其他线程均由该线程启动。JVM内部有两种线程:守护线程和非守护线程,main()属于非守护线程,守护线程通常由JVM自己使用,JAVA程序也可以标明自己创建的线程是守护线程。(3)JVM实例的消亡当程序中的所有非守护线程都终止时,JVM才退出;若安全管理器允许,程序也可以使用Runtime类或者System.exit()来退出。JVM、JRE、JDK的区别JVM:JAVA虚拟机所有的JAVA程序都是运行在JVM上,JVM是JRE的一部分JRE:JAVARuntimeEnvironment(JAVA运行环境)JRE主要用于执行JAVA程序,JRE除了包含JVM外还包含一些基础的JAVAAPI,JRE是JDK的一部份。JDK:JAVADevelopmentKit(JAVA开发工具包)JDK提供了JAVA的开发环境和运行环境(JRE),开发环境主要包含了一些开发工具,例如常用的JAVAc编译工具、jar打包执行程序、还有一些JVM监控工具等等JAVA的各种集成开发工具Eclipse、NetBean、IntelliJIDEA等JDK开发工具包JAVAc、jar等JRE运行环境JVMOS操作系统三大流行JVMSunHotSpotBeaJRockitIBMJ9使用最广泛的jvm,兼容性好,开源,无论使用于客户端或者服务端都有较好的性能,综合性能比较优秀执行效率最优秀的JVM,专注为服务器硬件和服务端应用场景高度优化的虚拟机,但启动慢,占内存,通常使用于Bea的中间件产品WebLogic上。与HostSpot定位比较接近,主要使用于IBM公司各种JAVA产品的执行平台,例如IBMWebSphere以及在IBMAIX和z/OS这些平台上部署的JAVA应用。除以上三个比较著名jvm外还有很多其它的JVM,例如:AzulVM、LiquidVM、SquawkVM等。Bea和Sun两家公司已分别于2008、2010被Oracle收购,未来oracle可能会整合hotSpot和Jrockit两个虚拟机的精华做出更出色的JVM2、Jvm基础知识及内存设置、监控2.1、JVM相关概念1、什么是JVM2、JVM能运行哪些编程语言3、JVM运行流程4、JVM生命周期5、三大流行的JVM2.2、JVM体系结构1、类加载器2、执行引擎3、运行时数据区4、本地库接口2.3、JVM内存参数调整及监控1、JVM之内存调整2、JVM监控工具之Jconsole3、JVM监控工具之JProfileJVM体系结构ClassFilesClassLoader类加载器方法区MethodArea虚拟机栈VMStack本地方法栈NativeMethodStack堆Heap程序计数器ProgramCounterRegisterRuntimeDataAreaJVM运行时数据区本地库接口NativeInterface本地方法库NativeLibraries所有线程共享的数据区线程隔离的数据区执行引擎ExecutionEngineJVM体系结构主要包含两个子系统和两个组件:ClassLoader(类加载器)子系统,ExecutionEngine(执行引擎)子系统RuntimDataArea(运行时数据区域)组件,NativeInterface(本地接口)组件JVM体系结构之类加载器ClassLoader类加载器类加载器负责加载JAVA类的字节代码到JAVA虚拟机中,可以根据指定的类名(如java.lang.Object)来装载class文件的内容到Runtimedataarea中的methodarea(方法区域)。JAVA程序员可以extendsjava.lang.ClassLoader类来写自己的Classloader。启动类加载器BootstrapClassLoader扩展类加载器ExtensionClassLoader应用程序类加载器ApplicationClassLoader用户自定义加载器UserClassLoader用户自定义加载器UserClassLoader类加载器双亲委派模型双亲委派模型工作过程如果一个类加载器接收到了类加载的请求,它首先把这个请求委托给他的父类加载器去完成,每个层次的类加载器都是如此,因此所有的加载请求都应该传送到顶层的启动类加载器中,只有当父加载器反馈自己无法完成这个加载请求(它在搜索范围中没有找到所需的类)时,子加载器才会尝试自己去加载。优点:java类随着它的类加载器一起具备了一种带有优先级的层次关系。例如类java.lang.Object,它存放在tools.jar中,无论哪个类加载器要加载这个类,最终都会委派给启动类加载器进行加载,因此Object类在程序的各种类加载器环境中都是同一个类。相反,如果用户自己写了一个名为java.lang.Object的类,并放在程序的Classpath中,那系统中将会出现多个不同的Object类,java类型体系中最基础的行为也无法保证,应用程序也会变得一片混乱。JVM体系结构之类加载器站在JVM的角度讲,主要有两种类型加载器:启动类加载器和所有其它的类加载器。启动类加载器是JVM实现的一部分,使用C++语言实现,其它类加载器都由java语言实现,独立于虚拟机外部,并且全部继承抽象类java.lang.ClassLoader(1)BootstrapClassLoader启动类加载器这是JVM的根ClassLoader,它是用C++实现的,JVM启动时初始化此ClassLoader,并由此ClassLoader完成$JAVA_HOME$中jre\lib\rt.jar(SunJDK的实现)中所有class文件的加载,这个jar中包含了java规范定义的所有接口以及实现。启动类加载器无法被JAVA程序直接引用。(2)ExtensionClassLoader扩展类加载器扩展类加载器负责加载JAVA_HOME\lib\ext目录中或者java.ext.dirs系统变量所指定的所有类库,开发者可以直接使用扩展类加载器。(3)ApplicationClassLoader应用程序类加载器JVM用此classloader来加载用户类路径(Classpath)上所指定的类库,包含指定的jar包以及目录,该加载器有时也称为系统类加载器。开发者可以直接使用这个类加载器,如果应用程序中没有自定义过自己的类加载器,一般情况下这个就是程序中默认的类加载器。(4)User-DefinedClassLoader用户自定义类加载器User-DefinedClassLoader是Java开发人员继承ClassLoader抽象类自行实现的ClassLoader,基于自定义的ClassLoader可用于加载非Classpath中的jar以及目录类加载器之类加载过程1.加载加载过程负责找到二进制字节码并加载至JVM中,JVM通过类名、类所在的包名通过ClassLoader来完成类的加载。2.连接链接过程负责对二进制字节码的格式进行校验、初始化装载类中的静态变量以及解析类中调用的接口、类。(1)验证:确保被导入类的正确性(2)准备:为类变量分配内存,并将其初始化为默认值(3)解析:把类中的符号引用转换为直接引用3.初始化初始化过程即为执行类中的静态初始化代码、构造器代码以及静态属性的初始化,在四种情况下初始化过程会被触发执行:调用了new;反射调用了类中的方法;子类调用了初始化;JVM启动过程中指定的初始化类加载验证准备解析初始化使用卸载类加载过程连接JVM体系结构ExecutionEngine执行引擎执行引擎是JVM最核心的组成部分之一,其主要是执行class中的指令,任何JVM实现的核心是Executionengine。执行引擎可以把JAVA字节码转为机器能识别的字节码,并调用机器的指令进行计算等,不同JVM的执行效率很大程度决定于他们各自实现的Executionengine的好坏。“虚拟机”的执行引擎与“物理机”的执行引擎是比较类似的,这两种机器都有执行代码能力,其区别是物理机的执行引擎是直接建立在处理器、硬件、指令集和操作系统层面上的,而虚拟机的执行引擎是自己实现的,因此虚拟机可以自行制定指令集与执行引擎的结构体系,并且能够执行那些不被硬件直接支持的指令。JAVANativeInterface(JNI)本地接口Java本地接口(JavaNativeInterface,JNI)是一个标准的JavaAPI,它支持将Java代码与使用其他编程语言编写的代码相集成,例如可以调用Native语言函数C\C++等。JNI是java与其它编程语言交互的接口。RuntimeDateArea运行时数据区这个组件就是JVM的内存区域,下面对这部分进行详细介绍。这是了解JVM内存模型的重要部分。JVM体系结构-运行时区域RuntimedataareaRuntimedataarea主要包括五个部分:Heap(堆)MethodArea(方法区域)VMStack(虚拟机栈),Nativemethodstack(本地方法栈)(在Sun的HotSpot虚拟机中VMStack和Nativemethodstack是合并到一起的)ProgramCounter(程序计数器)Heap和MethodArea是被所有线程的共享使用的;而vmstack,Programcounter和Nativemethodstack是以线程为粒度的,每个线程独自拥有。方法区MethodAr