深入理解Java运行

来源:互联网 发布:银行卡复印件制作软件 编辑:程序博客网 时间:2024/06/06 02:46

深入理解Java运行原理

   首先,我们先来聊一下一般高级语言的工作原理。我们在编辑器或者IDE里根据每种语言的语法规则敲入源代码,这些源代码以二进制的形式存储在我们电脑的硬盘中,当我们再次打开编辑器读取这些二进制文件的时候,编辑器或IDE会将原先存储在硬盘上的二进制文件还原成我们能够理解的英文。然而当我们运行程序的时候,CPU肯定是读不懂英文的,需要由编译器转换为二进制文件。有些编译器直接将源代码编译成机器码,载入内存后CPU可以直接运行,而机器码的格式是跟具体的CPU架构相关的,比如说Intel的CPU机器码对于ARM CPU来说是无法理解的。因此,同样的源代码需要根据不同的硬件进行编译。高级语言到第几语言的桥梁便是编译器。编译器将我们的源代码编译成可执行的机器码,然后CPU读取机器码执行程序。所以下C,C++语言编写的程序在不同的平台上运行时需要使用不同平台的编译器进行重新编译,从而生成相应平台的机器码,然后才能被对应平台的CPU执行。

一、Java语言的跨平台特性

  相信大家平时或多或少都会听说过Java语言跨平台的这个特性,所谓的跨平台是指Java编写的程序可以 ”write once, run anywhere” (meaning that compliedJava code can run on all platforms that support Java without the need forrecompilation)。

  Java语言也遵循源代码—>机器码,然而Java源代码(.java)经过java编译器(javac.exe)编译后并没有直接转换为机器码,而是转换为了一种中间格式,字节码(.class)。字节码再通过java虚拟机JVM转化成特定CPU架构的机器码(注:java语言编译后的字节码必须通过JVM才能执行)。JVM是一个“桥梁”是一个“中间件”是实现跨平台的关键,而跨平台的是Java程序,而非JVM,不同平台下需要安装不同版本的JVM:

图(1)不同平台下的JVM

官网下面也有对应不同平台的jdk下载的版本。

二、Java虚拟机的主要模块

  Java虚拟机用通俗的话来讲就是用软件的方式模拟出跟硬件类似的环境,最终的工作还是由原来机器的CPU来完成的,它会要求CPU给其一些内存,一些CPU的时间片。Java程序被编译以及执行的过程大致如下,其中Java Source(.java File)、Java Compiler (javac)、 Java Byte Code (.class File)我们都有大致的了解,下面我们具体来说一下Java 虚拟机中的ClassLoader模块。


图(2)Java程序运行的大致模块


  一个Java程序,不管是CS还是BS应用,都是由若干个.class文件组织而成的一个完整的Java应用程序,当程序在运行时,即会调用该程序的一个入口函数来调用系统的相关功能,而这些功能都被封装在不同的class文件当中,所以经常要从这个class文件中要调用另外一个class文件中的方法,如果另外一个文件不存在的,则会引发系统异常。而程序在启动的时候,并不会一次性加载程序所要用的所有class文件,而是根据程序的需要,通过Java的类加载机制(ClassLoader)来动态加载某个class文件到内存当中的,从而只有class文件被载入到了内存之后,才能被其它class所引用。所以ClassLoader就是用来动态加载class文件到内存当中用的。

Java默认提供的ClassLoader有三种BootStrap ClassLoader, ExtensionClassLoader. App ClassLoader。

BootStrapClassLoader: 启动加载器,是Java 类加载层次中最顶层的类加载器,负责加载JDK中的核心类库,如:rt.jar, resources.jar, charsets.jar等。

1.  URL[] urls = sun.misc.Launcher.getBootstrapClassPath().getURLs();  

2. for (int i = 0; i < urls.length; i++) {  

3.      System.out.println(urls[i].toExternalForm());  

4. }  


图(3)ClassLoader的体系架构

ExtensionClassLoader: 称为称为扩展类加载器,负责加载Java的扩展类库,默认加载JAVA_HOME/jre/lib/ext/目下的所有jar。

AppClassLoader: 系统类加载器,负责加载应用程序classpath目录下的所有jar和class文件。

类加器的原理介绍:ClassLoader使用的是双亲委托模型来搜索类的,每个ClassLoader实例都有一个父类加载器的引用(不是继承的关系,是一个包含的关系),虚拟机内置的类加载器(Bootstrap ClassLoader)本身没有父类加载器,但可以用作其它ClassLoader实例的的父类加载器。当一个ClassLoader实例需要加载某个类时,它会试图亲自搜索某个类之前,先把这个任务委托给它的父类加载器,这个过程是由上至下依次检查的,首先由最顶层的类加载器Bootstrap ClassLoader试图加载,如果没加载到,则把任务转交给Extension ClassLoader试图加载,如果也没加载到,则转交给App ClassLoader 进行加载,如果它也没有加载得到的话,则返回给委托的发起者,由它到指定的文件系统或网络等URL中加载该类。如果它们都没有加载到这个类时,则抛出ClassNotFoundException异常。否则将这个找到的类生成一个类的定义,并将它加载到内存当中,最后返回这个类在内存中的Class实例对象。

我们将会在下面的章节介绍JVM运行时的区域模块。


[1] http://blog.csdn.net/xyang81/article/details/7292380

[2] http://blog.csdn.net/bingduanlbd/article/details/8332664



0 0
原创粉丝点击