JVM启动过程——JVM之一
JVM是Java程序运行的环境,同时是一个操作系统的一个应用程序进程,因此它有自己的生命周期,也有自己的代码和数据空间.
JVM体系主要是两个JVM的内部体系结构分为三个子系统和两大组件,分别是:类装载器(ClassLoader)子系统、执行引擎子系统和GC子系统,组件是内存运行数据区域和本地接口。
JVM工作原理和特点主要是指操作系统装入JVM,是通过jdk中Java.exe来完成,通过下面4步来完成JVM环境.
1.创建JVM装载环境和配置
2.装载JVM.dll
3.初始化JVM.dll并挂界到JNIENV(JNI调用接口)实例
4.调用JNIEnv实例装载并处理class类。
一.JVM装入环境,JVM提供的方式是操作系统的动态连接文件.
既然是文件那就一个装入路径的问题,Java是怎么找这个路径的呢?
当你在调用Java test的时候,操作系统会在path下在你的Java.exe程序,Java.exe就通过下面一个过程来确定JVM的路径和相关的参数配置了.下面基于Windows的实现的分析:
1、首先查找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路径。
2、然后装载JVM.cfg文件JRE路径+\lib+\ARCH(CPU构架)+\JVM.cfg ,ARCH(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的文件路径.
二:装载JVM.dll
通过第一步已经找到了JVM的路径,Java通过LoadJavaVM来装入JVM.dll文件.装入工作很简单就是调用Windows API函数:
LoadLibrary装载JVM.dll动态连接库.然后把JVM.dll中的导出函数JNI_CreateJavaVM和JNI_GetDefaultJavaVMInitArgs挂接到InvocationFunctions变量的CreateJavaVM和GetDefaultJavaVMInitArgs函数指针变量上。JVM.dll的装载工作宣告完成。
三:初始化JVM,获得本地调用接口,这样就可以在Java中调用JVM的函数了.调用InvocationFunctions->CreateJavaVM也就是JVM中JNI_CreateJavaVM方法获得JNIEnv结构的实例.
四:运行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的主类名作为运行的主类。
之后会调用Java.c中LoadClass方法装载该主类(使用JNIEnv实例的FindClass)。
然后调用JNIEnv实例的GetStaticMethodID方法查找装载的class主类中“public static void main(String[] args)”方法,并判断该方法是否为public方法,然后调用JNIEnv实例的CallStaticVoidMethod方法调用该Java类的main方法。
JVM启动过程——JVM之一的更多相关文章
- JVM启动过程
JVM启动过程包括:加载.连接.初始化 1.加载:就是将class文件加载到内存.详细的说是,将class文件加载到运行时数据区的方法区内,然后在堆区创建一个java.lang.Class对象,用来封 ...
- JVM系列(一):jvm启动过程速览
jvm是java的核心运行平台,自然是个非常复杂的系统.当然了,说jvm是个平台,实际上也是个泛称.准确的说,它是一个java虚拟机的统称,它并不指具体的某个虚拟机.所以,谈到java虚拟机时,往往我 ...
- 038.[转] JVM启动过程与类加载
From: https://blog.csdn.net/luanlouis/article/details/40043991 Step 1.根据JVM内存配置要求,为JVM申请特定大小的内存空间 ? ...
- JVM启动过程 类加载器
下图来自:http://blog.csdn.net/jiangwei0910410003/article/details/17733153 package com.test.jvm.common; i ...
- JVM 启动参数及原理 转
Java虚拟机(JVM)是Java应用的运行环境,从一般意义上来讲,JVM是通过规范来定义的一个虚拟的计算机,被设计用来解释执行从Java源码编译而来的字节码.更通俗地说,JVM是指对这个规范的具体实 ...
- JVM类加载过程详细分析
双亲委派加载模型 为什么需要双亲委派加载模型 主要是为了安全,避免用户恶意加载破坏JVM正常运行的字节码文件,比如说加载一个自己写的java.util.HashMap.class.这样就有可能造成包冲 ...
- 查看JVM默认参数及微调JVM启动参数
目录 查看某个JVM进程堆内存信息 微调JVM启动参数 查看JVM的一些默认参数 参考廖雪峰老师的这篇 JVM调优的正确姿势: https://www.liaoxuefeng.com/article/ ...
- jvm学习006 jvm内存结构分配
主要内容如下: JVM启动流程 JVM基本结构 内存模型 编译和解释运行的概念 一.JVM启动流程: JVM启动时,是由java命令/javaw命令来启动的. 二.JVM基本结构: JVM基本结构图: ...
- CentOS7 Tomcat 启动过程很慢,JVM上的随机数与熵池策略
1. CentOS7 Tomcat 启动过程很慢 在centos启动官方的tomcat时,启动过程很慢,需要几分钟,经过查看日志,发现耗时在这里:是session引起的随机数问题导致的: <co ...
随机推荐
- 添加鼠标右键菜单项(EditPlus为例)
下载Editplus,发现大多是绿色版,这就导致鼠标右键快捷菜单了,使用起来不方面,上网搜集了下资料,解决方法很简单: 首先进入注册表:regedit 然后如图设置新项. 其中editplus是右键菜 ...
- 如何使用Prism框架的EventAggregator在模块间进行通信
目的 本文主要介绍如何使用Prism类库提供的事件机制在松耦合组件之间相互通信,Prism类库的事件机制建立在事件聚合服务之上,允许发布者和订阅者通过事件进行通信,不需要彼此之间引用. 事件聚合 Ev ...
- hdu 1355 The Peanuts
http://acm.hdu.edu.cn/showproblem.php?pid=1355 #include <cstdio> #include <iostream> #in ...
- 在Qt中怎样显示ASCII码大于127的字符
前段时间要显示“≤”符号找了挺久没找到方法,后面发现用以下方法可以解决: ushort gd[]={8805,0}; QString gteq=QString::fromUtf16(gd); 得 ...
- Socket也有专门的Unicode版本
https://www.chilkatsoft.com/refdoc/wcppCkSocketWRef.html https://www.chilkatsoft.com/refdoc/vcCkSock ...
- Apache Commons Pool2 源码分析 | Apache Commons Pool2 Source Code Analysis
Apache Commons Pool实现了对象池的功能.定义了对象的生成.销毁.激活.钝化等操作及其状态转换,并提供几个默认的对象池实现.在讲述其实现原理前,先提一下其中有几个重要的对象: Pool ...
- Ubuntu学习-简单指令
查看是否安装了中文支持 locale -a 如果有 zh_CN.utf8 则表示系统已经安装了中文locale,如果没有则需要安装相应的软件包. 软件管理 apt ( Advanced Packagi ...
- 用到的Python运算符
假设变量a为10,变量b为20. 算术运算符 比较运算符 赋值运算符 逻辑运算符 运算符优先级 对于逻辑运算符,not的优先级最大,or的优先级最小.它们三个的优先级排序为:not > and ...
- IOS Xmpp 创建固定房间
XMPPRoom *room; // 初始化房间 XMPPRoomCoreDataStorage *rosterstorage = [[XMPPRoomCoreDataStorage alloc] i ...
- 数据结构算法应用C++语言描述——(1)C++基础知识
一.二维数组 (1)二维数组的列是固定时,行未知时使用动态分配 当一个二维数组每一维的大小在编译时都是已知时,可以采用类似于创建一维数组的语法 来创建二维数组.例如,一个类型为char的7×5数组可用 ...