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` 文件是64位或32位的,与你的操作系统版本需要匹配。如果你的系统是64位的,但你安装的是32位的JDK,或者反之,就会导致这个问题。因此,确保你的JDK版本与操作系统架构相一致至关重要。例如,如果你的电脑...
jvm.dll应用程序,是开发PYCHARM常用的一个连接,所以能下载
VC调用java的简单例子。需要注意jvm.dll路径,路径不对就不能成功!
接下来,我们将深入探讨与这个 `jvm.dll` 文件相关的几个关键知识点。 ### 1. JVM (Java Virtual Machine) 概述 Java 虚拟机(JVM)是一种能够执行 Java 字节码的虚拟机。它提供了一个运行环境,使得 Java 程序...
解决win7下不能登录oracle ebs 11i环境用的必备文件
win7 64下EBS可用的jvm.dll文件,用于替换Jinitiator中的jvm.dll
在使用Eclipse集成开发环境时,可能会遇到一个常见的问题,即在启动Eclipse时收到“Failed to load the JNI shared library jvm.dll”的错误提示。这个错误通常表明Eclipse无法找到必要的Java虚拟机(JVM)组件来...
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"指的是两个特定的动态链接库文件,它们在Windows环境下用于串口通信开发。 首先,我们来理解一下64位和32位系统的基本区别。32位系统能够处理最大4GB的内存...
标签"jar"表明这些库文件也存在对应的Java档案文件(JAR),例如"rxtxSerial.jar"和"rxtxParallel.jar",这些JAR文件包含了Java源代码和相关的元数据,可以在Java项目中通过添加依赖来使用。开发者通常会将这些JAR...
`rxtxSerial.dll` 是RXTX库中的串口通信组件,它实现了Java虚拟机(JVM)与系统串行端口之间的桥梁。而`rxtxParallel.dll` 则对应并行通信功能,允许程序通过并行端口进行数据传输。这两个文件对于运行依赖于RXTX的...
综上所述,关于“ebs插件使用的新版jvm.dll文件”的理解,我们得知这是一个针对特定版本JVM DLL文件的技术文档。该文档主要涉及了JVM DLL文件的路径、版本变更、扩展名更改以及与EBS插件之间的关系等内容。这对于在...
flash builder 4.6里边的,有时候腾讯安全管家乱删,把这个删除了就没法用了,找了很久这个,都是07年版本,没法用,这个是09年版本。
正常安装和配置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 系统 ... 必须用管理员才能打开...
opera v5.0 hotel system
C或其他本地语言编写的程序可以通过调用`jvm.dll`接口直接在JVM上运行Java代码。 总结来说: - **java.exe**:用于启动带有控制台输出的Java应用程序。 - **javaw.exe**:用于启动无控制台的GUI Java应用程序,...
《hsdis.dll与Java二进制反汇编详解》 在深入探讨hsdis.dll之前,首先需要理解什么是DLL(Dynamic Link Library)。DLL是Windows操作系统中的一种共享库文件,它包含可由多个程序同时使用的代码和数据。hsdis.dll是...
tcnative-1.dll与APR一起工作,使得Tomcat能够利用这些底层功能,尤其是对于SSL加速,它可以直接使用操作系统的SSL堆栈,而不是通过Java的JSSE(Java Secure Socket Extension)。 在文件名称列表中,我们看到有两...
同时,hsdis-amd64.dll的源代码是开源的,这意味着开发者可以对其进行修改以适应特定的需求或扩展其功能。 在实际开发中,hsdis-amd64.dll的应用场景广泛。例如,当面临性能问题时,开发者可以使用它来查看哪些代码...