`

JVM.dll装载过程与源代码分析

    博客分类:
  • JVM
 
阅读更多
   JVM.dll装载过程与源代码分析
你知道JVM.dll转载过程吗,这里和大家分享一下,首先看一下它的概念,JVM.dll是一个包含可由多个程序同时使用的代码和数据的库。例如,在Windows操作系统中,Comdlg32DLL执行与对话框有关的常见函数。

浅谈JVM.dll装载过程与源代码分析

众所周知java.exe是javaclass文件的执行程序,但实际上java.exe程序只是一个执行的外壳,它会装载JVM.dll,这个动态连接库才是java虚拟机的实际操作处理所在。本文探究java.exe程序是如何查找和装载JVM.dll动态库,并调用它进行class文件执行处理的。

JVM.dll源代码

本文分析之代码,《JavaTM2SDK,StandardEdition,v1.4.2fcsCommunitySourceRelease》,可从sun官方网站下载,主要分析的源代码为:j2se\src\share\bin\java.cj2se\src\windows\bin\java_md.c

java.c是什么东西

‘java程序’源代码所谓‘java程序’,包括jdk中的java.exe\javac.exe\javadoc.exe,java.c源代码中通过JAVA_ARGS宏来控制生成的代码,如果该宏没定义则编译文件控制生成java.exe否则编译文件控制生成其他的‘java程序’。比如:j2se\make\java\javac\Makefile(这是javac编译文件)中:$(CD)../../sun/javac;$(MAKE)$@RELEASE=$(RELEASE)FULL_VERSION=$(FULL_VERSION)j2se\make\sun\javac\javac\Makefile(由上面Makefile文件调用)中:JAVA_ARGS="{\"-J-ms8m\",\"com.sun.tools.javac.Main\"}"则由同一份java.c代码生成的javac.exe程序就会直接调用java类方法:com.sun.tools.javac.Main,这样使其执行起来就像是直接运行的一个exe文件,而未定义JAVA_ARGS的java.exe程序则会调用传递过来参数中的类方法。

从java.c的main入口函数说起

main()函数中前面一段为重新分配参数指针的处理。然后调用函数:CreateExecutionEnvironment,该函数主要查找java运行环境的目录,和JVM.dll这个虚拟机核心动态连接库文件路径所在。根据操作系统不同,该函数有不同实现版本,但大体处理逻辑相同,我们看看windows平台该函数的处理(j2se\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函数调用windowsAPI函数GetModuleFileName取java.exe程序的绝对路径,以我的jdk安装路径为例,为:“D:\java\j2sdk1.4.2_04\bin\java.exe”,然后去掉文件名取绝对路径为:“D:\java\j2sdk1.4.2_04\bin”,之后会在去掉最后一级目录,现在绝对路径为:“D:\java\j2sdk1.4.2_04”。然后GetJREPath函数继续判断刚刚取的路径+\bin\java.dll组合成的这个java.dll文件是否存在,如果存在则“D:\java\j2sdk1.4.2_04”为JRE路径,否则判断取得的“D:\java\j2sdk1.4.2_04”路径+\jre\bin\java.dll文件是否存在,存在则“D:\java\j2sdk1.4.2_04\jre”为JRE路径。如果上面两种情况都不存在,则从注册表中去查找(参见函数GetPublicJREHome)。

函数:GetPublicJREHome先查找HKEY_LOCAL_MACHINE\Software\JavaSoft\JavaRuntimeEnvironment\CurrentVersion键值“当前JRE版本号”,判断“当前JRE版本号”是否为1.4做为版本号,如果是则取HKEY_LOCAL_MACHINE\Software\JavaSoft\JavaRuntimeEnvironment\“当前JRE版本号”\JavaHome的路径所在为JRE路径。

我的JDK返回的JRE路径为:“D:\java\j2sdk1.4.2_04\jre”。
◆b、装载jvm.cfg虚拟机动态连接库配置文件是通过java.c中函数:ReadKnownVMs实现的。

该函数首先组合jvm.cfg文件的绝对路径,JRE路径+\lib+\ARCH(CPU构架)+\jvm.cfgARCH(CPU构架)的判断是通过java_md.c中GetArch函数判断的,该函数中windows平台只有两种情况:WIN64的‘ia64’,其他情况都为‘i386’。我的为i386所以jvm.cfg文件绝对路径为:“D:\java\j2sdk1.4.2_04\jre\lib\i386\jvm.cfg”。文件内容如下:


##@(#)jvm.cfg 1.703/01/23##Copyright2003SunMicrosystems,Inc.Allrightsreserved.  #SUNPROPRIETARY/CONFIDENTIAL.Useissubjecttolicenseterms.  #####ListofJVMsthatcanbeusedasanoptiontojava,javac,etc.  #Orderisimportant--irstinthislististhedefaultJVM.  #NOTEthatthisboththisfileanditsformatareUNSUPPORTEDand  #WILLGOAWAYinafuturerelease.  ##YoumayalsoselectaJVMinanarbitrarylocationwiththe  #"-XXaltjvm="option,butthattooisunsupported  #andmaynotbeavailableinafuturerelease.  #-clientKNOWN-serverKNOWN-hotspotALIASED_TO-client-  classicWARN-nativeERROR-greenERROR  (如果细心的话,我们会发现在JDK目录中我的为:“D:\java\j2sdk1.4.2_04\jre\bin\client”和“D:\java\j2sdk1.4.2_04\jre\bin\server”两个目录下都存在JVM.dll文件。而java正是通过jvm.cfg配置文件来管理这些不同版本的JVM.dll的。)

ReadKnownVMs函数会将该文件中的配置内容读入到一个JVM配置结构的全局变量中,该函数首先跳过注释(以‘#’开始的行),然后读取以‘-’开始的行指定的jvm参数,每一行为一个jvm信息,第一部分为jvm虚拟机名称,第二部分为配置参数,比如行:“-clientKNOWN”则“-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”、“java-XXaltjvm=”或“java-J-XXaltjvm=”。如果是第一种参数传递方式,CheckJvmType函数会取参数‘-J’后面的jvm名称,然后从已知的jvm配置参数中查找如果找到同名的则去掉该jvm名称前的‘-’直接返回该值;而第二种方法,会直接返回“-XXaltjvm=”或“-J-XXaltjvm=”后面的jvm类型名称;如果在运行java时未指定上面两种方法中的任一一种参数,CheckJvmType会取配置文件中第一个配置中的jvm名称,去掉名称前面的‘-’返回该值。CheckJvmType函数的这个返回值会在下面的函数中汇同jre路径组合成JVM.dll的绝对路径。

比如:如果在运行java程序时使用“java-J-clienttest”则ReadKnownVMs会读取参数“-client”然后查找jvm.cfg读入的参数中是否有jvm名称为“-client”的,如果有则去掉jvm名称前的“-”直接返回“client”;而如果在运行java程序时使用如下参数:“java-XXaltjvm=D:\java\j2sdk1.4.2_04\jre\bin\clienttest”,则ReadKnownVMs会直接返回“D:\java\j2sdk1.4.2_04\jre\bin\client”;如果不带上面参数执行如:“javatest”,因为在jvm.cfg配置文件中第一个存在的jvm为“-client”,所以函数ReadKnownVMs也会去掉jvm名称前的“-”返回“client”。其实这三中情况都是使用的“D:\java\j2sdk1.4.2_04\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-clienttest”JVM.dll路径为:JRE路径+\bin+\jvm类型字符串+\JVM.dll按照我的JDK路径则为:“D:\java\j2sdk1.4.2_04\jre”+“\bin”+“\client”+“\JVM.dll”。第二种情况“java-XXaltjvm=D:\java\j2sdk1.4.2_04\jre\bin\clienttest”路径为:jvm类型字符串+\JVM.dll即为:“D:\java\j2sdk1.4.2_04\jre\bin\client”+“\JVM.dll”第三种情况“javatest”为:“D:\java\j2sdk1.4.2_04\jre”+“\bin”+“\client”+“\JVM.dll”与情况一相同。所以这三种情况都是调用的jvm动态连接库“D:\javaj2sdk1.4.2_04\jre\bin\client\JVM.dll”处理test类的。

我们来进一步验证一下:打开cmd控制台:

设置java装载调试E:\work\java_research>set_JAVA_LAUNCHER_DEBUG=1

情况一E:\work\java_research>java-J-clienttest.ScanDirectory----_JAVA_LAUNCHER_DEBUG----
分享到:
评论

相关推荐

    jvm.dll文件

    `jvm.dll` 文件是64位或32位的,与你的操作系统版本需要匹配。如果你的系统是64位的,但你安装的是32位的JDK,或者反之,就会导致这个问题。因此,确保你的JDK版本与操作系统架构相一致至关重要。例如,如果你的电脑...

    jvm.dll应用程序下载软件链接

    jvm.dll应用程序,是开发PYCHARM常用的一个连接,所以能下载

    CCallJava.rar_c++ jvm_java dll_jvm_jvm.dll_vc jvm.dll

    VC调用java的简单例子。需要注意jvm.dll路径,路径不对就不能成功!

    ebs原版本jvm.dll文件

    接下来,我们将深入探讨与这个 `jvm.dll` 文件相关的几个关键知识点。 ### 1. JVM (Java Virtual Machine) 概述 Java 虚拟机(JVM)是一种能够执行 Java 字节码的虚拟机。它提供了一个运行环境,使得 Java 程序...

    win7用JVM.DLL

    解决win7下不能登录oracle ebs 11i环境用的必备文件

    win7 64下EBS可用的jvm.dll文件

    win7 64下EBS可用的jvm.dll文件,用于替换Jinitiator中的jvm.dll

    启动 Eclipse 弹出 Failed to load the JNI shared library jvm.dll 错误的解决方法

    在使用Eclipse集成开发环境时,可能会遇到一个常见的问题,即在启动Eclipse时收到“Failed to load the JNI shared library jvm.dll”的错误提示。这个错误通常表明Eclipse无法找到必要的Java虚拟机(JVM)组件来...

    gdal.jar, gdalconstjni.dll, gdaljni.dll, ogrjni.dll

    2. **gdalconstjni.dll, gdaljni.dll, ogrjni.dll**: 这些是JNI(Java Native Interface)动态链接库,是Java与C/C++代码交互的桥梁。GDAL和OGR(Open Geospatial Library,用于处理矢量数据)的核心功能实现是在C++...

    64位与32位 rxtxserial.dll/rxtxParallel.dll

    标题中的"64位与32位 rxtxserial.dll/rxtxParallel.dll"指的是两个特定的动态链接库文件,它们在Windows环境下用于串口通信开发。 首先,我们来理解一下64位和32位系统的基本区别。32位系统能够处理最大4GB的内存...

    将rxtxSerial.dll和rxtxParallel.dll下载

    标签"jar"表明这些库文件也存在对应的Java档案文件(JAR),例如"rxtxSerial.jar"和"rxtxParallel.jar",这些JAR文件包含了Java源代码和相关的元数据,可以在Java项目中通过添加依赖来使用。开发者通常会将这些JAR...

    windows64位 rxtxserial.dll、rxtxParallel.dll

    `rxtxSerial.dll` 是RXTX库中的串口通信组件,它实现了Java虚拟机(JVM)与系统串行端口之间的桥梁。而`rxtxParallel.dll` 则对应并行通信功能,允许程序通过并行端口进行数据传输。这两个文件对于运行依赖于RXTX的...

    ebs插件使用的新版jvm.dll文件

    综上所述,关于“ebs插件使用的新版jvm.dll文件”的理解,我们得知这是一个针对特定版本JVM DLL文件的技术文档。该文档主要涉及了JVM DLL文件的路径、版本变更、扩展名更改以及与EBS插件之间的关系等内容。这对于在...

    jvm.dll flash

    flash builder 4.6里边的,有时候腾讯安全管家乱删,把这个删除了就没法用了,找了很久这个,都是07年版本,没法用,这个是09年版本。

    IntelliJ IDEA 2019.3.1 x64 启动 failed to load jvm dll 用管理员才能打开的根本解决办法

    正常安装和配置JDK后,IntelliJ IDEA 2019.3.1 x64 启动仍然报 Failed to load JVM DLL 路径\jvm.dll if you already have a 64-bit JDK installed, define a JAVA_HOME variable in 系统 ... 必须用管理员才能打开...

    jvm.dll-opera

    opera v5.0 hotel system

    Windows下java、javaw、javaws以及jvm.dll等进程的区别

    C或其他本地语言编写的程序可以通过调用`jvm.dll`接口直接在JVM上运行Java代码。 总结来说: - **java.exe**:用于启动带有控制台输出的Java应用程序。 - **javaw.exe**:用于启动无控制台的GUI Java应用程序,...

    hsdis.dll.zip

    《hsdis.dll与Java二进制反汇编详解》 在深入探讨hsdis.dll之前,首先需要理解什么是DLL(Dynamic Link Library)。DLL是Windows操作系统中的一种共享库文件,它包含可由多个程序同时使用的代码和数据。hsdis.dll是...

    tcnative-1.dll(1.1.17和1.1.20)

    tcnative-1.dll与APR一起工作,使得Tomcat能够利用这些底层功能,尤其是对于SSL加速,它可以直接使用操作系统的SSL堆栈,而不是通过Java的JSSE(Java Secure Socket Extension)。 在文件名称列表中,我们看到有两...

    hsdis-amd64.dll

    同时,hsdis-amd64.dll的源代码是开源的,这意味着开发者可以对其进行修改以适应特定的需求或扩展其功能。 在实际开发中,hsdis-amd64.dll的应用场景广泛。例如,当面临性能问题时,开发者可以使用它来查看哪些代码...

Global site tag (gtag.js) - Google Analytics