java启动过程探索
详细过程记录图:http://download.csdn.net/source/2487652
喜欢Java,却苦于不知如何发布自己的应用,限制因素包括不知如何精简的jre,带着70~80M的身体,一处编写,到处适用就不怎么现实了。
网上搜索了大把的关于jre如何精简的资料,可是却读不懂,放了一阵,后来看到一本台湾王森的一本《java深度历险》,对Java的启动有所了解了,也就能成功的实行jre的精简了。
站在前人的肩膀上,总结了一下现在jre6的jvm启动过程。供有兴趣的朋友分享。
首先,要明白jre6/bin目录下的java.exe只不过是个外壳,也叫包装器。
其的作用是
1. 方便调用
2. 完成jvm.dll的加载
3. 还有版本控制的功能
Java.exe的核心作用就是找到jvm.dll并启动它
Jvm.dll 可以理解为就是java虚拟机
第一节:首先我们来看Java.exe的执行过程。
1. 将jre6拷贝到D盘新建的目录temp下。
2. 将temp/jre6/bin/java.exe拷贝到temp目录中.
3. 打开cmd,运行java –version命令:
系统提示:
C:/Documents and Settings/Administrator>java -version
Registry key 'Software/JavaSoft/Java Runtime Environment/CurrentVersion'
has value '1.3', but '1.6' is required.
Error: could not find java.dll
Error: could not find Java SE Runtime Environment.
【如果没有出现错误信息,可将CurrentVersion改为1.3,参考第4步】
很明显,系统当前为1.3.而当前的java.exe要求为1.6发生了版本冲突。
4. 运行regedit命令:打开注册表
展开[HKEY_LOCAL_MACHINE/SOFTWARE/JavaSoft/Java Runtime Environment]
发现CurrentVersion显示为1.3
【如果没有出现错误信息,可将CurrentVersion改为1.3】
将当前版本改为1.6,再次运行java –version命令,出现了版本信息如下:
C:/Documents and Settings/Administrator>java -version
java version "1.6.0_20"
Java(TM) SE Runtime Environment (build 1.6.0_20-b02)
Java HotSpot(TM) Client VM (build 16.3-b01, mixed mode, sharing)
注意:此版本信息为java.exe找到的jvm.dll的版本信息。
5. 键入 path 命令,显示如下信息:
C:/Documents and Settings/Administrator>path
PATH=D:/Program Files/JavaFX/javafx-sdk1.3/bin;D:/Program Files/JavaFX/javafx-sd
k1.3/emulator/bin;C:/WINDOWS/system32;C:/WINDOWS;C:/WINDOWS/System32/Wbem;C:/Pro
gram Files/Common Files/Thunder Network/KanKan/Codecs;C:/Program Files/SinoVoice
/jTTS 5.0 Desktop/Bin;C:/Program Files/Microsoft SQL Server/80/Tools/Binn/;D:/Pr
ogram Files/Microsoft SQL Server/90/DTS/Binn/;D:/Program Files/Microsoft SQL Ser
ver/90/Tools/binn/;D:/Program Files/Microsoft SQL Server/90/Tools/Binn/VSShell/C
ommon7/IDE/;C:/Program Files/Microsoft Visual Studio 8/Common7/IDE/PrivateAssemb
lies/;D:/Program Files/MySQL/MySQL Server 5.1/bin
不同电脑会有不同
6. 键入:set path=”” 设置路径为空,再次运行path命令,结果如下:
C:/Documents and Settings/Administrator>path
PATH=""
此时path路径已经清空了。
7. 再次运行java –verison命令,结果如下:
C:/Documents and Settings/Administrator>java -version
'java' 不是内部或外部命令,也不是可运行的程序
或批处理文件。
系统提示找不到java了
8. 转到D盘的temp目录,并运行java –version ,结果如下:
D:/temp>java -version
java version "1.6.0_20"
Java(TM) SE Runtime Environment (build 1.6.0_20-b02)
Java HotSpot(TM) Client VM (build 16.3-b01, mixed mode, sharing)
OK,又出现java版本信息了,说明运行又正常了。但此时运行的是那个jvm.dll呢?
9. 现在,打开注册表,将[HKEY_LOCAL_MACHINE/SOFTWARE/JavaSoft/Java Runtime Environment/1.6]下的JavaHome的值进行修改:只需将D://Program Files//Java//jre6中的jre6修改为jre60j即可。再次运行java -version 提示如下:
D:/temp>java -version
Error: could not open `D:/Program Files/Java/jre60/lib/i386/jvm.cfg'
没错:因为jre60这个目录更本不存在,所以,java.exe找不到jvm.cfg jvm的配置信息
10. Ok,将jre6改回来,再次运行,OK了。说明java.exe是通过javaHome去找jvm.cfg的。
11. 再次修改注册表中的当前版本为1.3。执行Java –version 结果又出现版本不正确了,说明这是后Java.exe又跑到注册表中去找信息了。
12. 转到jre6/bin目录,执行java –version命令,又看到正常的版本信息了。这是和解呢?
13. 怀疑是java.dll在作怪,拷贝java.dll放到temp目录中,现在temp目录中有java.exe和java.dll了,再次运行java –version命令,还是不行呀,还是版本不正确的信息,
14. 将java.exe和java.dll剪切到jre6目录下,转到jre6目录,执行java –version命令,还是,不行???
15. 可能是bin目录在做怪,修改原来的bin目录名为bin2,新建一个新的bin目录,将java.exe和java.dll放到bin中,转到bin目录,执行java –version命令,又报错了,提示:
D:/temp/jre6/bin>java –version
Error: no `client' JVM at `D:/temp/jre6/bin/client/jvm.dll'.
总算不出现版本错误了。说明java.exe不去找注册表的信息了。
但是找不到jvm.dll
这个很自然了。因为现在的bin目录就两个文件,怎么来的jvm.dll
你可以将client目录拷贝过来试试。
16. cmd转到temp目录,将bin目录中的java.exe拷贝到jre6目录下,删除bin目录,将bin目录恢复为bin目录,将jre6目录修改为jre目录。Cmd再转到jre目录,执行java –version
结果又看到了正常的版本信息了。
这说明,java.exe寻找jvm.cfg的方式很多种。
通过很多试验:总算搞清了jave.exe启动的过程了
首先在文件目录中找java.dll
1. 当前目录是否有java.dll
2. 父目录是否有bin目录,其中的bin目录是否存在java.dll『案例:java.exe在lib目录中也能正常找到java.dll』
找到java.dll后,再根据不同版本的java.exe所指定的路径寻找jvm.cfg【jvm配置文件,告诉程序去哪里找jvm】
如果找不到java.dll再去系统注册表中找:
首先判断java的版本是否匹配,由
[HKEY_LOCAL_MACHINE/SOFTWARE/JavaSoft/Java Runtime Environment]
CurrentVersion 的值决定。
根据对应的java版本找对应的javahome参数:
javavhome保存了对应版本的jre目录所在的物理路径的绝对位置。根据jre目录找到jvm.cfg.然后就是根据jvm.cfg找到要用的jvm.dll了。
还是用图形来说明形象些,也好理解和记忆些;
结论:
Java.exe只是根据自身携带的信息找到jvm.cfg配置文件,然后根据jvm配置文件启动jvm.dll,运行Java虚拟机的一个程序外壳而已。
携带信息包括:
自身对应的Java版本号。
对应版本的jvm.cfg配置文件存放的路径。
Java就是通过这样的启动方式,来控制Java的版本的
Thomas
2010-6-25