- 浏览: 420025 次
- 性别:
- 来自: 广州
文章分类
最新评论
-
xiaomuxingren:
你好,请问update-alternatives --inst ...
JDK8安装及jenkins安装 -
wahahachuang8:
我觉得这种东西自己开发太麻烦了,就别自己捣鼓了,找个第三方,方 ...
HTML5 WebSocket -
晨曦的朝阳:
刚好有需求,学习一下!
MySql主从配置 -
mfkvfn:
这是恶意的商业竞争呀
解决 android 微信5.0及后续版本无法打开电话号码的问题 -
fwyhf:
require('./monitor/module_liste ...
NodeJS Server 进程自动重启
众所周知 java.exe 是 java class 文件的执行程序,但实际上 java.exe 程序只是一个执行的外壳,它会装载 jvm.dll ( windows 下,下皆以 windows 平台为例, linux 下和 solaris 下其实类似,为: libjvm.so ),这个动态连接库才是 java 虚拟机的实际操作处理所在。文探究 java.exe 程序是如何查找和装载 jvm.dll 动态库,并调用它进行 class 文件执行处理的。
源代码
本文分析之代码,《 JavaTM 2 SDK, Standard Edition, v1.4.2 fcsCommunity Source Release 》,可从 sun 官方网站下载,主分析的源代码为:
j2se\src\share\bin\java.c
j2se\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\Java Runtime Environment\CurrentVersion 键值“当前 JRE 版本号”,判断“当前 JRE 版本号”是否为 1.4 做为版本号,如果是则取 HKEY_LOCAL_MACHINE\Software\JavaSoft\Java Runtime Environment\ “当前 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.7 03/01/23
#
# Copyright 2003 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\j2sdk1.4.2_04\jre\bin\client ”和“ :\java\j2sdk1.4.2_04\jre\bin\server ”两个目录下都存在 jvm.dll 文件。而 java 正是通过 jvm.cfg 配置文件来管理这些不同版本的 jvm.dll 的。)
ReadKnownVMs 函数会将该文件中的配置内容读入到一个 JVM 配置结构的全局变量中,该函数首先跳过注释(以‘ # ’开始的行),然后读取以‘ - ’开始的行指定的 jvm 参数,每一行为一个 jvm 信息,第一部分为 jvm 虚拟机名称,第二部分为配置参数,比如行:“ -client KNOWN ”则“ -client ”为虚拟机名称,而“ KNOWN ”为配置类型参数,“ KNOWN ”表示该虚拟机的 jvm.dll 存在,而“ LIASED_TO ”表示为另一个 jvm.dll 的别名,“ WARN ”表示该虚拟机的 jvm.dll 不存在但运行时会用其他存在的 jvm.dll 替代执行,而“ ERROR ”同样表示该类虚拟机的 jvm.dll 不存在且运行时不会找存在的 jvm.dll 替代而直接抛出错误信息。
在运行 java 程序时指定使用那个虚拟机的判断是由 java.c 中函数: CheckJvmType 判断,该函数会检查 java 运行参数中是否有指定 jvm 的参数,然后从 ReadKnownVMs 函数读取的
发表评论
-
JDK8安装及jenkins安装
2017-11-28 11:48 31511、下载 jdk-8u144-linux-x64.tar.gz ... -
JDK7安装
2017-02-13 16:43 748ppa源安装jdk7的下载链接已经被删除 所以自己安装JDK ... -
记录扫描嗅探与反扫描嗅探的那些事
2016-09-10 10:45 930批量嗅探 1、知道ID为自増如http://www.aa.co ... -
Spring的事务机制
2016-07-13 15:33 447事务原理 原子性 一致性 隔离性 持续性 M ... -
链接加密防篡改方法
2016-06-22 14:51 1517链接加密防篡改方法 对所有参数进行排序,然后尾部加入key参 ... -
学好Java基础的几本书
2011-11-13 20:53 2661学好Java基础的几本书 每一门语言及技术都 ... -
Java 日志管理
2011-06-28 14:59 1639Logger.java //Level.java Log ... -
如何写好Java代码(转载)
2011-03-23 11:50 1481转载自:http://developer.51 ... -
jprofiler使用心得,你不知道的那些事
2010-10-12 08:25 995听说jprofiler和另一个工具都是可以用来跟踪及检查某Ja ... -
Java动态代理
2010-08-23 15:01 13061.什么是Java动态代理 代理:一种设计模式,其目 ... -
JAVA反射机制
2009-05-13 16:59 903JAVA 反射机制是在运行状态中,对于任意一个类,都能 ... -
java套接字处理
2009-05-13 16:58 1267HTTP 头部详解及使用 Java 套接字处理 H ... -
类初始化顺序(非常明了)
2009-05-13 16:55 1078超类静态变量. ------------- 超类静态初始化 ... -
jvm指令解析
2009-05-13 16:54 3575//源代码 class TT{ st ... -
Pattern正则表达式
2009-05-13 16:52 1803Pattern (Java 2 Platform SE 6) ... -
正则表达式的四种基本用法
2009-05-13 16:51 1141正则表达式在字符串处理上有着强大的功能,sun在jdk1.4加 ... -
时间格式
2009-05-13 16:51 21881、通过MessageFormat转化 String da ... -
synchronized
2009-05-13 16:49 10581、synchronized的定义 2、sy ... -
invokevirtual,invokespecial,invokestatic,invokein
2009-05-13 16:48 4771invokevirtual,invokespecial,in ... -
jvm的javap 指令及格式
2009-05-13 16:47 2084我们可以看到, 类初始化正是按照源文件中定义的原文顺序 ...
相关推荐
源码解析jdk7.0集合:ArrayList的底层实现原理.pdf
JDK动态代理的底层实现原理
源码解析jdk7.0集合:HashSet的底层实现原理.pdf
源码解析jdk7.0集合:LinkedList的底层实现原理.pdf
通过JDK动态代理机制实现增强,来理解AOP底层的实现
基于java的jdk动态代理, 比较了静态代理与动态代理的区别,以及动态代理的底层实现,反编译class文件 jdk动态代理和cglib的区别
源码解析jdk8.0集合:HashMap的底层实现原理.pdf
代理模式详解-jdk与cglib动态代理与底层实现,spring中常用的设计模式,本案例是从源码到代理模式的实现。
Jdk的Timer 实现定时器,本例代码包括Handler 发送消息的简单实现过程 定时器 Timer,在这里演示一个进度条不断更新
Spring Aop的底层实现技术 --- Jdk动态代理原理 很不错的一篇文章
02-JDK1.7中的HashMap底层实现分析.mp4
03-JDK1.8中的HashMap底层实现分析.mp4
这是google翻译过来的JDK9的API中文版,里面包含了所有JDK9实现的类库这是google翻译过来的JDK9的API中文版,里面包含了所有JDK9实现的类库
JDK11安装包,JDK11安装包JDK11安装包,JDK11安装包JDK11安装包,JDK11安装包JDK11安装包,JDK11安装包JDK11安装包,JDK11安装包JDK11安装包,JDK11安装包JDK11安装包,JDK11安装包JDK11安装包,JDK11安装包JDK11...
使用jdk proxy实现aop机制的一个小例子,写着给新手看看而已,老手们莫见笑
jdk1.8+springMVC实现http接口rsa加密解密
jdk8帮助文档jdk8帮助文档jdk8帮助文档jdk8帮助文档jdk8帮助文档jdk8帮助文档jdk8帮助文档jdk8帮助文档jdk8帮助文档jdk8帮助文档jdk8帮助文档jdk8帮助文档jdk8帮助文档jdk8帮助文档jdk8帮助文档jdk8帮助文档jdk8帮助...
idea+springboot+MySQL+jdk1.8实现简单的注册登录功能,本代码从最简单的spring boot架构实现登录注册,适合新手拿去练手!
纯jdk6实现的webservice,非常好用! 可以实现非常简单的发布方法和远程调用机制。
mac系统jdk1.8安装包!mac系统jdk1.8安装包!mac系统jdk1.8安装包!mac系统jdk1.8安装包!mac系统jdk1.8安装包!mac系统jdk1.8安装包!mac系统jdk1.8安装包!mac系统jdk1.8安装包!mac系统jdk1.8安装包!mac系统jdk...