知识大全 java源代码分析----jvm.dll装载过程

Posted 函数

篇首语:青春不以山海为远,志愿只向家国未来。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 java源代码分析----jvm.dll装载过程相关的知识,希望对你有一定的参考价值。

   简述    众所周知java exe是java class文件的执行程序 但实际上java exe程序只是  一个执行的外壳 它会装载jvm dll(windows下 以下皆以windows平台为例   linux下和solaris下其实类似 为 libjvm so) 这个动态连接库才是java  虚拟机的实际操作处理所在 本文探究java exe程序是如何查找和装载jvm dll  动态库 并调用它进行class文件执行处理的      源代码    本文分析之代码 《JavaTM SDK Standard Edition v fcs  Community Source Release》 可从sun官方网站下载 主要分析的源代码为   j se\\src\\share\\bin\\java c  j se\\src\\windows\\bin\\java_md c     java c是什么东西     java程序 源代码  所谓 java程序 包括jdk中的java exe\\javac exe\\javadoc exe java c源  代码中通过JAVA_ARGS宏来控制生成的代码 如果该宏没定义则编译文件控制生  成java exe否则编译文件控制生成其他的 java程序   比如   j se\\make\\java\\javac\\Makefile(这是javac编译文件)中   $(CD) / /sun/javac ; $(MAKE) $@ RELEASE=$(RELEASE) FULL_VERSION=$(FULL_VERSION)  j se\\make\\sun\\javac\\javac\\Makefile(由上面Makefile文件调用)中   JAVA_ARGS = \\ J ms m\\ \\ sun tools javac Main\\   则由同一份java c代码生成的javac exe程序就会直接调用java类方法    sun tools javac Main 这样使其执行起来就像是直接运行的一个exe文件   而未定义JAVA_ARGS的java exe程序则会调用传递过来参数中的类方法      从java c的main入口函数说起    main()函数中前面一段为重新分配参数指针的处理   然后调用函数 CreateExecutionEnvironment 该函数主要查找java运行环境的  目录 和jvm dll这个虚拟机核心动态连接库文件路径所在 根据操作系统不同   该函数有不同实现版本 但大体处理逻辑相同 我们看看windows平台该函数的处  理(j se\\src\\windows\\bin\\java_md c)     CreateExecutionEnvironment函数主要分为三步处理   a 查找jre路径   b 装载jvm cfg中指定的虚拟机动态连接库(jvm dll)参数   c 取jvm dll文件路径      实现     a 查找jre路径是通过java_md c中函数 GetJREPath实现的   该函数首先调用GetApplicationHome函数 GetApplicationHome函数调用windows  API函数GetModuleFileName取java exe程序的绝对路径 以我的jdk安装路径为例   为 D:\\java\\j sdk _ \\bin\\java exe 然后去掉文件名取绝对路径为    D:\\java\\j sdk _ \\bin 之后会在去掉最后一级目录 现在绝对路径为    D:\\java\\j sdk _   然后GetJREPath函数继续判断刚刚取的路径+\\bin\\java dll组合成的这个java dll  文件是否存在 如果存在则 D:\\java\\j sdk _ 为JRE路径 否则判断取得  的 D:\\java\\j sdk _ 路径+\\jre\\bin\\java dll文件是否存在 存在则   D:\\java\\j sdk _ \\jre 为JRE路径 如果上面两种情况都不存在 则从注  册表中去查找(参见函数GetPublicJREHome)      函数 GetPublicJREHome先查找  HKEY_LOCAL_MACHINE\\Sofare\\JavaSoft\\Java Runtime Environment\\CurrentVersion  键值 当前JRE版本号 判断 当前JRE版本号 是否为 做为版本号 如果是则  取HKEY_LOCAL_MACHINE\\Sofare\\JavaSoft\\Java Runtime Environment\\ 当前JRE版本号   \\JavaHome的路径所在为JRE路径     我的JDK返回的JRE路径为 D:\\java\\j sdk _ \\jre     b 装载jvm cfg虚拟机动态连接库配置文件是通过java c中函数:ReadKnownVMs实现  的   该函数首先组合jvm cfg文件的绝对路径 JRE路径+\\lib+\\ARCH(CPU构架)+\\jvm cfg  ARCH(CPU构架)的判断是通过java_md c中GetArch函数判断的 该函数中windows平  台只有两种情况 WIN 的 ia 其他情况都为 i 我的为i 所以jvm cfg  文件绝对路径为 D:\\java\\j sdk _ \\jre\\lib\\i \\jvm cfg 文件内容如  下   ## @(#)jvm cfg  / / # # Copyright Sun Microsystems Inc All rights reserved # SUN PROPRIETARY/CONFIDENTIAL Use is subject to license terms # # ### List of JVMs that can be used as an option to java javac etc # Order is important first in this list is the default JVM # NOTE that this both this file and its format are UNSUPPORTED and# WILL GO AWAY in a future release ## You may also select a JVM in an arbitrary location with the# XXaltjvm=<jvm_dir> option but that too is unsupported# and may not be available in a future release # client KNOWN server KNOWN hotspot ALIASED_TO client classic WARN native ERROR green ERROR    (如果细心的话 我们会发现在JDK目录中我的为 D:\\java\\j sdk _ \\jre\\bin\\client 和 D:\\java\\j sdk _ \\jre\\bin\\server 两个目录下都存在jvm dll文件 而java正是通过jvm cfg配置文件来管理这些不同版本的jvm dll的 )    ReadKnownVMs函数会将该文件中的配置内容读入到一个JVM配置结构的全局变量中 该函数首先跳过注释(以 # 开始的行) 然后读取以 开始的行指定的jvm参数 每一行为一个jvm信息 第一部分为jvm虚拟机名称 第二部分为配置参数 比如行    client KNOWN 则 client 为虚拟机名称 而 KNOWN 为配置类型参数 KNOWN   表示该虚拟机的jvm dll存在 而 ALIASED_TO 表示为另一个jvm dll的别名 WARN   表示该虚拟机的jvm dll不存在但运行时会用其他存在的jvm dll替代执行 而 ERROR   同样表示该类虚拟机的jvm dll不存在且运行时不会找存在的jvm dll替代而直接抛出错误  信息     在运行java程序时指定使用那个虚拟机的判断是由java c中函数 CheckJvmType判断 该函数会检查java运行参数中是否有指定jvm的参数 然后从ReadKnownVMs函数读取的jvm cfg数据结构中去查找 从而指定不同的jvm类型(最终导致装载不同jvm dll) 有两种方法可以指定jvm类型 一种按照jvm cfg文件中的jvm名称指定 第二种方法是直接指定 它们执行的方法分别是 java J<jvm cfg中jvm名称> java XXaltjvm=<jvm类型名称> 或 java J XXaltjvm=<jvm类型名称> 如果是第一种参数传递方式 CheckJvmType函数会取参数 J 后面的jvm名称 然后从已知的jvm配置参数中查找如果找到同名的则去掉该jvm名称前的 直接返回该值 而第二种方法 会直接返回 XXaltjvm= 或 J XXaltjvm= 后面的jvm类型名称 如果在运行java时未指定上面两种方法中的任一一种参数 CheckJvmType会取配置文件中第一个配置中的jvm名称 去掉名称前面的 返回该值 CheckJvmType函数的这个返回值会在下面的函数中汇同jre路径组合成jvm dll的绝对路径     比如 如果在运行java程序时使用 java J client test 则ReadKnownVMs会读取参数 client 然后查找jvm cfg读入的参数中是否有jvm名称为 client 的 如果有则去掉jvm名称前的 直接返回 client 而如果在运行java程序时使用如下参数    java XXaltjvm=D:\\java\\j sdk _ \\jre\\bin\\client test 则ReadKnownVMs  会直接返回 D:\\java\\j sdk _ \\jre\\bin\\client 如果不带上面参数执行如    java test 因为在jvm cfg配置文件中第一个存在的jvm为 client 所以函数  ReadKnownVMs也会去掉jvm名称前的 返回 client 其实这三中情况都是使用的   D:\\java\\j sdk _ \\jre\\bin\\client\\jvm dll 这个jvm动态连接库处理test这个class的 见下面GetJVMPath函数     c 取jvm dll文件路径是通过java_md c中函数 GetJVMPath实现的   由上面两步我们已经获得了JRE路径和jvm的类型字符串 GetJVMPath函数判断CheckJvmType  返回的jvm类型字符串中是否包含了 \\ 或 / 如果包含则以该jvm类型字符串+\\jvm dll作为JVM的全路径 否则以JRE路径+\\bin+\\jvm类型字符串+\\jvm dll作为JVM的全路径     看看上面的例子 第一种情况 java J client test jvm dll路径为   JRE路径+\\bin+\\jvm类型字符串+\\jvm dll 按照我的JDK路径则为    D:\\java\\j sdk _ \\jre + \\bin + \\client + \\jvm dll   第二种情况 java XXaltjvm=D:\\java\\j sdk _ \\jre\\bin\\client test 路径为   jvm类型字符串+\\jvm dll即为 D:\\java\\j sdk _ \\jre\\bin\\client + \\jvm dll   第三种情况 java test 为 D:\\java\\j sdk _ \\jre + \\bin + \\client   + \\jvm dll 与情况一相同 所以这三种情况都是调用的jvm动态连接库 D:\\javaj sdk _ \\jre\\bin\\client\\jvm dll 处理test类的     我们来进一步验证一下   打开cmd控制台     设置java装载调试  E:\\work\\java_research>set _JAVA_LAUNCHER_DEBUG=     情况一  E:\\work\\java_research>java J client test ScanDirectory   _JAVA_LAUNCHER_DEBUG cha138/Article/program/Java/hx/201311/26750

相关参考

知识大全 Java类使用类装载器实现装载文件

Java类使用类装载器实现装载文件  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  viewpla

知识大全 Java的类装载器和命名空间

Java的类装载器和命名空间  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  摘要 &n

知识大全 列表排序代码分析

Java编程技巧:列表排序代码分析  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  在JavaCo

知识大全 java资源获取分析

  在开发java程序的过程中我们经常要做的一件事就是获取资源那么什么是资源呢?说白了在计算机里那就是一堆数据只是这堆数据对我们的java程序有多种表现形式一般来说有FileURLInputStrea

知识大全 利用DES加密算法保护Java源代码

利用DES加密算法保护Java源代码  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  Java语言

知识大全 源代码--Java写小游戏,吞食蛇

源代码--Java写小游戏,吞食蛇  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  java新手简

知识大全 拷贝文件的Java源代码

拷贝文件的Java源代码  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  //ClassCopyF

知识大全 Java线程控制权源代码的深入探讨

Java线程控制权源代码的深入探讨  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  Java线程控

知识大全 Java线程通信源代码中的奥秘探究

Java线程通信源代码中的奥秘探究  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  Java线程通

知识大全 java非对称加密的源代码(RSA)

java非对称加密的源代码(RSA)  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  鉴于rsa加