- 浏览: 431263 次
- 性别:
- 来自: 广州
-
文章分类
最新评论
-
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 33671、下载 jdk-8u144-linux-x64.tar.gz ... -
JDK7安装
2017-02-13 16:43 821ppa源安装jdk7的下载链接已经被删除 所以自己安装JDK ... -
记录扫描嗅探与反扫描嗅探的那些事
2016-09-10 10:45 983批量嗅探 1、知道ID为自増如http://www.aa.co ... -
Spring的事务机制
2016-07-13 15:33 499事务原理 原子性 一致性 隔离性 持续性 M ... -
链接加密防篡改方法
2016-06-22 14:51 1594链接加密防篡改方法 对所有参数进行排序,然后尾部加入key参 ... -
学好Java基础的几本书
2011-11-13 20:53 2703学好Java基础的几本书 每一门语言及技术都 ... -
Java 日志管理
2011-06-28 14:59 1681Logger.java //Level.java Log ... -
如何写好Java代码(转载)
2011-03-23 11:50 1526转载自:http://developer.51 ... -
jprofiler使用心得,你不知道的那些事
2010-10-12 08:25 1029听说jprofiler和另一个工具都是可以用来跟踪及检查某Ja ... -
Java动态代理
2010-08-23 15:01 13491.什么是Java动态代理 代理:一种设计模式,其目 ... -
JAVA反射机制
2009-05-13 16:59 943JAVA 反射机制是在运行状态中,对于任意一个类,都能 ... -
java套接字处理
2009-05-13 16:58 1310HTTP 头部详解及使用 Java 套接字处理 H ... -
类初始化顺序(非常明了)
2009-05-13 16:55 1126超类静态变量. ------------- 超类静态初始化 ... -
jvm指令解析
2009-05-13 16:54 3629//源代码 class TT{ st ... -
Pattern正则表达式
2009-05-13 16:52 1851Pattern (Java 2 Platform SE 6) ... -
正则表达式的四种基本用法
2009-05-13 16:51 1191正则表达式在字符串处理上有着强大的功能,sun在jdk1.4加 ... -
时间格式
2009-05-13 16:51 22491、通过MessageFormat转化 String da ... -
synchronized
2009-05-13 16:49 11071、synchronized的定义 2、sy ... -
invokevirtual,invokespecial,invokestatic,invokein
2009-05-13 16:48 4837invokevirtual,invokespecial,in ... -
jvm的javap 指令及格式
2009-05-13 16:47 2134我们可以看到, 类初始化正是按照源文件中定义的原文顺序 ...
相关推荐
本文将深入探讨JDK10的底层实现,特别是C++源码以及HotSpot虚拟机的源码,帮助开发者更好地理解和优化Java应用程序。 首先,让我们了解JDK10的关键特性: 1. **局部变量类型推断(Local-Variable Type Inference,...
Spring AOP 的底层实现技术 --- Jdk 动态代理原理 JDK 动态代理是 Spring AOP 的底层实现技术,允许开发者在运行期创建接口的代理实例。在 JDK 1.3 以后,JDK 动态代理技术提供了实现 AOP 的绝好底层技术。JDK 动态...
JDK动态代理的底层实现原理
基于java的jdk动态代理, 比较了静态代理与动态代理的区别,以及动态代理的底层实现,反编译class文件 jdk动态代理和cglib的区别
根据提供的文件信息,以下是对JDK 8.0中HashMap实现原理的详细知识点介绍: 1. HashMap概述 HashMap是Java集合框架的一部分,它实现了Map接口,用于存储键值对。其核心特点在于基于哈希表的映射机制,能够通过键...
4. **底层实现原理**: - **JDK代理**:JDK动态代理使用反射和InvocationHandler接口生成一个实现了目标接口的新类。在运行时,这个新类的实例作为代理对象,它的方法调用都会转发到InvocationHandler的`invoke()`...
JDK(Java Development Kit)是Oracle公司提供的Java开发工具包,而OpenJDK(Open Java Development Kit)则是一个开源版本的JDK实现,两者都包含了Java运行环境(JRE)和开发工具。JDK8是Java编程语言的一个重要...
03-JDK1.8中的HashMap底层实现分析.mp4
02-JDK1.7中的HashMap底层实现分析.mp4
### Windows中如何实现JDK7和JDK8的完美切换 在Windows环境下,为了满足不同项目的开发需求,经常需要在不同的JDK版本之间进行切换。本文将详细介绍如何在Windows操作系统中实现JDK7与JDK8之间的完美切换,并确保...
JDK11安装包,JDK11安装包JDK11安装包,JDK11安装包JDK11安装包,JDK11安装包JDK11安装包,JDK11安装包JDK11安装包,JDK11安装包JDK11安装包,JDK11安装包JDK11安装包,JDK11安装包JDK11安装包,JDK11安装包JDK11...
jdk8帮助文档jdk8帮助文档jdk8帮助文档jdk8帮助文档jdk8帮助文档jdk8帮助文档jdk8帮助文档jdk8帮助文档jdk8帮助文档jdk8帮助文档jdk8帮助文档jdk8帮助文档jdk8帮助文档jdk8帮助文档jdk8帮助文档jdk8帮助文档jdk8帮助...
《深入解析JDK7:基于C++的底层源码与HotSpot虚拟机剖析》 在IT领域,Java作为一门广泛使用的编程语言,其性能优化和内部机制一直是开发者关注的焦点。JDK7作为Java发展历程中的一个重要版本,引入了许多创新特性,...
Mac 版本 jdk 11 Mac 版本 jdk 11 Mac 版本 jdk 11Mac 版本 jdk 11 Mac 版本 jdk 11 Mac 版本 jdk 11Mac 版本 jdk 11 Mac 版本 jdk 11 Mac 版本 jdk 11Mac 版本 jdk 11 Mac 版本 jdk 11 Mac 版本 jdk 11Mac 版本 jdk...
同时,为了在不同的项目中切换不同版本的JDK,可以利用工具如JEnv或手动调整系统路径来实现。 总结这三个版本,JDK6奠定了现代Java的基础,JDK7带来了语言层面的改进,而JDK8则引领了Java向函数式编程的转变。这些...
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...
首先,JDK6的底层源码包含了大量的C++代码,这是因为Java虚拟机(JVM)的部分实现,如垃圾收集器、编译器等,都是用C++编写的。这些源码揭示了Java如何在操作系统级别进行交互,例如内存管理、线程调度等。通过阅读...
此外,模块化系统(Project Jigsaw)虽然在JDK 8中未完全实现,但为后续版本奠定了基础。 JDK 11是2018年的LTS版本,它在JDK 8的基础上继续优化并增加了新特性。例如,正式引入了模块化系统(Jigsaw),这使得大型...
JDK7安装包.zip\JDK7安装包.zip\JDK7安装包.zip\JDK7安装包.zip\JDK7安装包.zip JDK7安装包.zip\JDK7安装包.zip\JDK7安装包.zip\JDK7安装包.zip\JDK7安装包.zip JDK7安装包.zip\JDK7安装包.zip\JDK7安装包.zip\JDK7...
总的来说,深入研究JDK源码可以帮助我们更好地理解Java的底层机制,提高编程效率,解决复杂问题,并有助于开发出更健壮、高效的代码。同时,这也有助于遵循最佳实践,编写出更符合Java语言特性的软件。