jvm加载class的过程,class文件在jvm上运行

  jvm加载class的过程,class文件在jvm上运行

  00-1010一、JVM二介绍。JVM III的组件。JVM加载类文件的原理和机制

  

目录

JVM是Java虚拟机(Java Virtual Machine)的缩写。JVM是计算设备的规范。它是一台虚拟的计算机,是在一台实际的计算机上模拟各种计算机功能而实现的。

 

  Java语言的一个很重要的特点就是平台无关性。使用Java虚拟机是实现这一功能的关键。一般的高级语言要想在不同的平台上运行,需要编译成不同的目标代码。但引入Java虚拟机后,Java在不同平台运行时不需要重新编译。Java语言利用Java虚拟机屏蔽平台相关信息,使得Java语言编译器只需生成运行在Java虚拟机上的目标代码(字节码),无需修改即可运行在多种平台上。Java虚拟机在执行字节码时,将字节码解释为特定的平台及其指令执行。这就是Java可以“编译一次,到处运行”的原因。

  

一、JVM简介

 

  从图中可以看出,JVM运行在操作系统上,它与硬件没有直接的交互。

  1.类装入器

  类加载器的作用是将类文件加载到内存中,比如编写一个HelloWorld.java程序,然后通过javac编译生成类文件。类装入器将类文件装入内存。但是,类加载器对加载类文件有格式要求。注意:类加载器只要符合文件结构就加载,能不能运行由执行引擎负责。2.执行引擎Execution Engine执行引擎也称为解释器,负责解释命令并提交给操作系统执行。3.本地接口Native Interface本地接口的作用是为Java集成不同的编程语言。它的初衷是集成C/C程序。Java诞生的时候,C/C横行。想要站稳脚跟,必须要有一个聪明睿智的调用C/C程序,所以你在内存中开辟了一个专门的区域来处理标记为native的代码。其具体方法是在原生方法栈中注册原生方法,在执行引擎执行时加载原生库。目前这种方法只能在硬件相关的应用中使用,在企业应用中并不多见,因为异构域之间的通信非常发达,比如Socket通信和WebService。4.运行数据区运行时数据区运行数据区是整个JVM的重点。我们写的所有程序在开始运行前都是在这里加载的。Java生态系统如此繁荣,得益于这个地区极佳的自治性。

  

二、JVM的组成部分

1.Java中的Java类必须加载到JVM中才能运行。这种加载是由JVM中的类加载器完成的。类加载器所做工作的本质是将类文件从硬盘读入内存,其功能是在运行时加载类。Java类装入器基于三种机制:委托、可见性和一体性。(1)委托机制是将加载类的请求交给父类加载器,如果这个父类加载器找不到或者加载不到这个类,那么就重新加载。(2)可见性原则是子类的加载器可以看到父类加载器加载的所有类,而父类加载器看不到子类加载器加载的类。(3)单一性原则是指一个类只加载一次,通过委托机制保证子类加载器不会再次加载父类加载器加载的类。2.Java中的类大致可以分为三种:(1)系统类;(2)扩展班;(3)程序员定义的类;以及(3)类加载有两种方式:(1)隐式加载:当程序遇到通过new等方式生成或使用类或子类对象的静态域时。它隐式调用类加载器将相应的类加载到JVM中。(2)显式加载:通过调用Class.forName()或class loader . load class(class name)等方法显式加载所需的类。4.类加载的动态特性表明,一个应用程序总是由N个类组成。当Java程序启动时,它不会一次加载所有的类,然后运行它们。他总是将保证程序运行的基础类一次性加载到JVM中,其他类等到JVM使用它们。这是为了节省内存开销,因为Java本来就是为嵌入式系统设计的,内存很珍贵,使用时重新加载也是Java动态性的一种表现。5.Java类加载器Java中的类加载器本质上也是一个类。它的功能是将类加载到JVM中。值得注意的是,JVM中有三个类装入器。原因如下:一方面要明确分工,各自负责自己的区块;另一方面,实现委托模式。层次如下:BootStrap Loader——负责加载系统类。

 

  ExtClassLoader(扩展类加载器)-负责加载扩展类AppClassLoade(应用类加载器)r -负责加载应用类6。如何协调类装入器之间的工作Java中有三种类装入器。当一个类需要加载时,Java使用委托模型机制来协调。

  调和区分该由哪个类加载器完成。简单来说就是,类装载器有载入类的需求时,会先请示其Parent使用其搜索路径帮忙载入,如果Parent找不到,那么才由自己依照自己的搜索路径搜索类。实例一:

  

package ClassLoaderTest;public class ClassLoaderTest { public static void main(String[] args) { ClassLoader c1 = ClassLoaderTest.class.getClassLoader(); System.out.println(c1); ClassLoader c1Parent = c1.getParent(); System.out.println(c1Parent); ClassLoader c1Root = c1Parent.getParent(); System.out.println(c1Root); }}

执行结果:

 

  

 

  可以看出ClassLoaderTest是由AppClassLoader加载器加载的。AppClassLoader的Parent加载器是ExtClassLoader。但是ExtClassLoader的Parent是null,在Java中是无法获取的。实例二:

  

public class Test2 { public void test(){ System.out.println(Test2.class); System.out.println(this.getClass()); System.out.println(Test2.class.getClassLoader()); }}public class Test1 { public static void main(String[] args) { System.out.println(Test1.class.getClassLoader()); Test2 test2 = new Test2(); test2.test(); }}

执行结果:

 

  

 

  7. 预先加载和依需求加载Java运行环境为了优化系统,提高程序的执行速度,在JRE运行的开始会将Java运行所需要的基本类采用预先加载(pre-loading)的方法全部加载到内存当中,因为这些单元在Java程序运行的过程当中要经常使用的,主要包括JRE的rt.jar文件里面所有的.class文件。当java.exe虚拟机开始运行以后,它会找到安装在机器上的JRE环境,然后把控制权交给JRE,JRE的类加载器会自动将lib目录下的rt.jar基础类别文件库加载进内存,这些文件是Java程序执行所必需的,所以系统在开始就将这些文件加载,避免以后的多次IO操作,从而提高程序执行效率。然而我们在程序中需要使用自定义的类的时候就要使用依需求加载(load-on-demand)的方式,就是在Java程序需要用到的时候再加载,以减少内存的消耗。8. ClassLoader中一些 重要的方法

  

 

  9.什么地方适用类加载器最经典的例子就是AppletClassLoader,他被用来加载Applet使用的类,而Applet大部分是在网上使用,而非本地的操作系统使用。使用不同的类加载器,你可以从不同的源地址加载同一个类,它们被视为不同的类。J2EE使用多个类加载器加载不同地方的类,例如War文件由Web-app类加载器加载,而EJB-JAR中的类由另外的类加载器加载。有些服务器也支持热部署,这是由类加载器实现。你也可以使用类加载器来加载数据库或者其他持久层的数据。10. 类加载器的阶层体系Java类加载器的工作原理:当执行Java的.class文件的时候,java.exe会帮助我们找到jRE,接着找到JRE内部的jcm.dll,这才是真正的Java虚拟机器,最后加载动态库,激活Java虚拟机器。虚拟机激活以后,会先做一些初始化的动作,比如说读取系统参数等。一旦初始化动作完成后,就会产生第一个类加载器-----Bootstrap Loader,Bootstrap Loader是由C++撰写而成,这个Bootstrap所做的初始工作中,除了一些基本的初始化动作之外,最重要的就是加载Launcher.java之中的ExtClassLoader,并设定其parent为null,代表其父加载器为BootstrapLoader。然后Bootstrap loader再要求加载Launcher.java之中的AppClassLoader,并设定其parent为之前产生的ExtClassLoader实体。这两个类加载器都是以静态类的形式存在的。注意:Launcher E x t C l a s s L o a d e r . c l a s s 与 L a u n c h e r ExtClassLoader.class与Launcher ExtClassLoader.class与LauncherAppClassLoader.class都是由Bootstrap Loader所加载,所以Parent和由哪个类加载器加载没有关系。三者之间的关系:Bootstrap Loader <—(extends)-----ExtClassLoader <—(extends)—AppClassLoader这三个类加载器构成了Java的类加载体系。它们分别从以下的路径寻找程序所需要的类:Bootstrap Loader:sun.boot.class.pathExtClassLoader:java.ext.dirsAppClassLoader:java.class.path这三个参数可以通过System.getProperty()函数得到具体对应的路径。

  到此这篇关于JVM加载class文件的原理机制的文章就介绍到这了,更多相关JVM加载class文件内容请搜索盛行IT以前的文章或继续浏览下面的相关文章希望大家以后多多支持盛行IT!

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: