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路径。(当jvm启动失败的时候可以检查一下classpath和HKEY_LOCAL_MACHINE上的路径是否正确)

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.主要的内容如下:

  1. -client KNOWN
  2. -server KNOWN
  3. -hotspot ALIASED_TO -client
  4. -classic WARN
  5. -native ERROR
  6. -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的启动流程的更多相关文章

  1. Java内存管理-初始JVM和JVM启动流程(二)

    勿在流沙住高台,出来混迟早要还的. 做一个积极的人 编码.改bug.提升自己 我有一个乐园,面向编程,春暖花开! 上一篇分享了什么是程序,以及Java程序运行的三个阶段.也顺便提到了Java中比较重要 ...

  2. Jvm(jdk8)源码分析1-java命令启动流程详解

    JDK8加载源码分析 1.概述 现在大多数互联网公司都是使用java技术体系搭建自己的系统,所以对java开发工程师以及java系统架构师的需求非常的多,虽然普遍的要求都是需要熟悉各种java开发框架 ...

  3. JVM启动流程

    JVM启动流程 (1)在java中jvm是通过java或javaw命令启动的,后面跟加载的类名. (2)jvm在启动的时候先根据[当前路径和系统版本寻找jvm的配置文件jvm.cfg]装载配置. (3 ...

  4. JVM源码分析之JVM启动流程

      原创申明:本文由公众号[猿灯塔]原创,转载请说明出处标注 “365篇原创计划”第十四篇. 今天呢!灯塔君跟大家讲: JVM源码分析之JVM启动流程 前言: 执行Java类的main方法,程序就能运 ...

  5. Spring Boot启动流程详解(一)

    环境 本文基于Spring Boot版本1.3.3, 使用了spring-boot-starter-web. 配置完成后,编写了代码如下: @SpringBootApplication public ...

  6. Java虚拟机JVM学习01 流程概述

    Java虚拟机JVM学习01 流程概述 Java虚拟机与程序的生命周期 一个运行时的Java虚拟机(JVM)负责运行一个Java程序. 当启动一个Java程序时,一个虚拟机实例诞生:当程序关闭退出,这 ...

  7. spring 启动流程

    AbstractApplicationContext 分析 启动流程 // Prepare this context for refreshing.prepareRefresh(); 1. // In ...

  8. storm启动流程

    email:chenguibin2004@126.com storm: 是一个分布式的实时流式计算框架,具有低延迟.高可用.分布式.可扩展.数据不丢失的特点, storm包含四个核心组件: Nimbu ...

  9. cassandra 服务启动流程

    cassandra 服务启动流程 1.  setup 1)   CassandraDaemon ->main publicstaticvoidmain(String[]args) { insta ...

随机推荐

  1. BI就是报表?

    实际上,报表只是BI的一部分,虽然BI应用的结果通常需要通过报表来展示,但是,BI绝对不仅仅是报表.其实,大家对这些概念的理解,如同15年前的ERP一样.1998年,国内两大巨头金蝶与用友都开始宣称从 ...

  2. Sql分隔字符串方法--split

    SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO --DEClARE @str varchar(500)='a,b2,v5,d3,ew,2,3,dd' ...

  3. L17 怎么向应用程序商店提交应用

    原地址:https://developer.apple.com/library/ios/#referencelibrary/GettingStarted/RoadMapiOS/ApplicationD ...

  4. HDU 1875 畅通工程再续 (prim最小生成树)

    B - 畅通工程再续 Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit S ...

  5. 再论pyquery

    发现对于QQ群 空间文件的抓取毫无办法. QQ空间的代码可圈可点: 做了一个js的“客户端”,第一次加载时,将文件的列表信息全部抓取出来,然后基于js进行翻页和排序. 因此,想要抓取js渲染的dom, ...

  6. 生成PHP数组文件

    1. 解释型语言的妙处之一,在于可以动态生成代码再调用执行~2. 对于数据量不大(几千条?)的(key,value),存成数组文件,执行查找操作,效率应该是好于数据库操作的:3. php的数组,是ha ...

  7. SCOPE_IDENTITY的作用

    SCOPE_IDENTITY返回插入到同一作用域中的 IDENTITY 列内的最后一个 IDENTITY 值.一个作用域就是一个模块——存储过程.触发器.函数或批处理.因此,如果两个语句处于同一个存储 ...

  8. wsp反编译

    最后出于好奇,我把wsp文件解压缩,看看里面是什么(如果您的机器上的压缩软件不能直接解压,可尝试修改后缀名为cab.).我看到的首先是一个清单文件(manifest.xml),一个DLL文件(Shar ...

  9. 【leetcode】Best Time to Buy and Sell Stock II

    Best Time to Buy and Sell Stock II Say you have an array for which the ith element is the price of a ...

  10. 【转】如何调试bash脚本

    本文转自:http://coolshell.cn/articles/1379.html Bash 是Linux操作系统的默认Shell脚本.Shell是用来处理操作系统和用户交互的一个程序.Shell ...