没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
Java 中 JVM
Java 中 JVM 作用和特征,JVM 是什么
JVM 简介
JVM 是 Java Virtual Machine(Java 虚拟机)的缩写,JVM 是一种用于计算设备的规
范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现
的。Java 虚拟机包括一套字节码指令集、一组寄存器、一个栈、一个垃圾回收堆和一个存
储方法域。 JVM 屏蔽了与具体操作系统平台相关的信息,使 Java 程序只需生成在 Java 虚
拟机上运行的目标代码(字节码),就可以在多种平台上不加修改地运行。JVM 在执行字节
码时,实际上最终还是把字节码解释成具体平台上的机器指令执行。
JVM 是 JRE 的一部分。它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟
各种计算机功能来实现的。JVM 有自己完善的硬件架构,如处理器、堆栈、寄存器等,还
具有相应的指令系统。Java 语言最重要的特点就是跨平台运行。使用 JVM 就是为了支持与
操作系统无关,实现跨平台。
JVM 作用
Java 中的所有类,必须被装载到 jvm 中才能运行,这个装载工作是由 jvm 中的类装载器
完成的,类装载器所做的工作实质是把类文件从硬盘读取到内存中
JVM 对中央处理器(CPU)所执行的一种软件操作,用于执行编译过的 Java 程序码
(Applet 与应用程序)。
JVM 就是我们常说的 java 虚拟机,它是整个 java 实现跨平台的最核心的部分,所有的
java 程序会首先被编译为.class 的类文件,这种类文件可以在虚拟机上执行。也就是说 class
并不直接与机器的操作系统相对应,而是经过虚拟机间接与操作系统交互,由虚拟机将程序
解释给本地系统执行。当然只有 JVM 还不能成 class 的执行,因为在解释 class 的时候 JVM
需要调用解释所需要的类库 lib,而 jre 包含 lib 类库。
JVM 屏蔽了与具体操作系统平台相关的信息,使得 Java 程序只需生成在 Java 虚拟机上
运行的目标代码(字节码),就可以在多种平台上不加修改地运行。
JVM 特性
1)移植性
无论是 GC 还是 Hotspot 都可以用在任何 Java 可用的地方。比方说,JRuby 可以运行在其
他平台上,Rails 应用就可以运行在 IBM 主机上的 JRuby 上,而且这台 IBM 主机运行的是
CP/CMS。实际上,由于 Java 和 OpenJDK 项目的开源,我们正在看到越来越多的平台的
衍生,因此 JVM 的移植性也将越来越棒。
2)成熟
JVM 已有超过 15 年的历史,在过去的这些年里,许多开发者为它做出了许多贡献,使得它
的性能一次又一次地提升,让 JVM 变得更加稳定、快速和广泛。
3)覆盖面
JRuby 和 JVM 上的其他语言项目已经被开发者所承认,一个典型的例子是 invokedynamic
specification (aka JSR292)。JSR 越来越配合新的语言,JVM 已不再是 Java 一个人定制规
则。JVM 正在构建成为类如 JRuby 等项目的优良平台。
JVM 工作原理
JVM 是 java 的核心和基础,在 java 编译器和 os 平台之间的虚拟处理器。它是一种利用软
件方法实现的抽象的计算机基于下层的操作系统和硬件平台,可以在上面执行 java 的字节
码程序。
java 编译器只要面向 JVM,生成 JVM 能理解的代码或字节码文件。Java 源文件经编译成
字节码程序,通过 JVM 将每一条指令翻译成不同平台机器码,通过特定平台运行。
JVM 在整个 jdk 中处于最底层,负责于操作系统的交互,用来屏蔽操作系统环境,提供一个完
整的 Java 运行环境,因此也就虚拟计算机. 操作系统装入 JVM 是通过 jdk 中 Java.exe 来
完成,通过下面 4 步来完成 JVM 环境.
1.创建 JVM 装载环境和配置
首先查找 jre 路径,Java 是通过 GetApplicationHome api 来获得当前的 Java.exe 绝对
路径,c:\j2sdk1.4.2_09\bin\Java.exe,那么它会截取到绝对路径 c:\j2sdk1.4.2_09\,
判断 c:\j2sdk1.4.2_09\bin\Java.dll 文件是否存在,如果存在就把 c:\j2sdk1.4.2_09\
作为 jre 路径,如果不存在则判断 c:\j2sdk1.4.2_09\jre\bin\Java.dll 是否存在,如果
存在这 c:\j2sdk1.4.2_09\jre 作为 jre 路径.如果不存在调用 GetPublicJREHome 查
HKEY_LOCAL_MACHINE\Software\JavaSoft\Java Runtime Environment\“当前
JRE 版本号”\JavaHome 的路径为 jre 路径。
然后装载 JVM.cfg 文件 JRE 路径+\lib+\ARCH(CPU 构架)+\JVM.cfgARCH(CPU 构
架)的判断是通过 Java_md.c 中 GetArch 函数判断的,该函数中 windows 平台只有两
种情况:WIN64 的‘ia64’,其他情况都为‘i386’。以我的为例:
C:\j2sdk1.4.2_09\jre\lib\i386\JVM.cfg.主要的内容如下:
-client KNOWN
-server KNOWN
-hotspot ALIASED_TO -client
-classic WARN
-native ERROR
-green ERROR
在我们的 jdk 目录中 jre\bin\server 和 jre\bin\client 都有 JVM.dll 文件存在,而 Java
正是通过 JVM.cfg 配置文件来管理这些不同版本的 JVM.dll 的.通过文件我们可以定义目
前 jdk 中支持那些 JVM,前面部分(client)是 JVM 名称,后面是参数,KNOWN 表示 JVM
存在,ALIASED_TO 表示给别的 JVM 取一个别名,WARN 表示不存在时找一个 JVM 替代,
ERROR 表示不存在抛出异常.在运行 Java XXX 是,Java.exe 会通过 CheckJVMType
来检查当前的 JVM 类型,Java 可以通过两种参数的方式来指定具体的 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 的绝对路径。如果没有指定这会使用 JVM.cfg 中第一个定义的 JVM.可
以通过 set _Java_LAUNCHER_DEBUG=1 在控制台上测试.
最后获得 JVM.dll 的路径,JRE 路径+\bin+\JVM 类型字符串+\JVM.dll 就是 JVM 的文件
路径了,但是如果在调用 Java 程序时用-XXaltJVM=参数指定的路径 path,就直接用
path+\JVM.dll 文件做为 JVM.dll 的文件路径.
2.装载 JVM.dll
通过第一步已经找到了 JVM 的路径,Java 通过 LoadJavaVM 来装入 JVM.dll 文件.装入
工作很简单就是调用 Windows API 函数:
LoadLibrary 装载 JVM.dll 动态连接库.然后把 JVM.dll 中的导出函数 JNI_CreateJavaVM
和 JNI_GetDefaultJavaVMInitArgs 挂接到 InvocationFunctions 变量的 CreateJavaVM
和 GetDefaultJavaVMInitArgs 函数指针变量上。JVM.dll 的装载工作宣告完成。
3.初始化 JVM.dll 并挂界到 JNIENV(JNI 调用接口)实例
初始化 JVM,获得本地调用接口,这样就可以在 Java 中调用 JVM 的函数了.调用
InvocationFunctions->CreateJavaVM 也就是 JVM 中 JNI_CreateJavaVM 方法获得
JNIEnv 结构的实例.
4.运行 JAVA 程序。
Java 程序有两种方式一种是 jar 包,一种是 class. 运行 jar,Java -jar XXX.jar 运行的时候,
Java.exe 调用 GetMainClassName 函数,该函数先获得 JNIEnv 实例然后调用 Java 类
Java.util.jar.JarFileJNIEnv 中方法 getManifest()并从返回的 Manifest 对象中取
getAttributes("Main-Class")的值即 jar 包中文件:META-INF/MANIFEST.MF 指定的
Main-Class 的主类名作为运行的主类。之后 main 函数会调用 Java.c 中 LoadClass 方法装
载该主类(使用 JNIEnv 实例的 FindClass)。main 函数直接调用 Java.c 中 LoadClass 方
法装载该类。如果是执行 class 方法。main 函数直接调用 Java.c 中 LoadClass 方法装载该
类。
然后 main 函数调用 JNIEnv 实例的 GetStaticMethodID 方法查找装载的 class 主类中
“public static void main(String[] args)”方法,并判断该方法是否为 public 方法,然后
剩余49页未读,继续阅读
资源评论
Andy&lin
- 粉丝: 98
- 资源: 214
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功