JVM启动流程(JDK8)

JVM启动流程(JDK8)

JVM的启动入口是位于jdk/src/share/bin/java.c的JLI_Launch函数,其定义如下:

int
JLI_Launch(int argc, char ** argv,              /* main argc, argc */int jargc, const char** jargv,          /* java args */int appclassc, const char** appclassv,  /* app classpath */const char* fullversion,                /* full version defined */const char* dotversion,                 /* dot version defined */const char* pname,                      /* program name */const char* lname,                      /* launcher name */jboolean javaargs,                      /* JAVA_ARGS */jboolean cpwildcard,                    /* classpath wildcard */jboolean javaw,                         /* windows-only javaw */jint     ergo_class                     /* ergnomics policy */
);
1.初始化
InitLauncher(javaw);  //初始化启动器
DumpState();  //打印当前状态
//确保开启启动器跟踪状态
if (JLI_IsTraceLauncher()) {int i;printf("Command line args:\n");for (i = 0; i < argc ; i++) {printf("argv[%d] = %s\n", i, argv[i]);}AddOption("-Dsun.java.launcher.diag=true", NULL);
}
2.选择jre版本

解析参数,读取manifest文件,jre版本校验,加载jre以便确认是否存在,最后将相关环境变量放置好。

SelectVersion(argc, argv, &main_class);
3.创建JVM执行环境

确定数据模型,是32位还是64位,以及jvm本身的一些配置在jvm.cfg文件中读取和解析

CreateExecutionEnvironment(&argc, &argv,jrepath, sizeof(jrepath), //jre路径jvmpath, sizeof(jvmpath), //jvm路径jvmcfg,  sizeof(jvmcfg)); //jvm配置文件
4.加载jvm.so库

动态加载jvm.so这个共享库,并把jvm.so中的相关函数导出并且初始化

if (!IsJavaArgs()) {// 设置一些特殊的环境变量SetJvmEnvironment(argc,argv);}ifn.CreateJavaVM = 0;ifn.GetDefaultJavaVMInitArgs = 0;if (JLI_IsTraceLauncher()) {start = CounterGet();     // 记录启动时间}// 加载VM, 重中之重if (!LoadJavaVM(jvmpath, &ifn)) {return(6);}if (JLI_IsTraceLauncher()) {end   = CounterGet();}JLI_TraceLauncher("%ld micro seconds to LoadJavaVM\n",(long)(jint)Counter2Micros(end-start));++argv;--argc;// 解析更多参数信息if (IsJavaArgs()) {/* Preprocess wrapper arguments */TranslateApplicationArgs(jargc, jargv, &argc, &argv);if (!AddApplicationOptions(appclassc, appclassv)) {return(1);}} else {/* Set default CLASSPATH */cpath = getenv("CLASSPATH");if (cpath == NULL) {cpath = ".";}SetClassPath(cpath);}/* Parse command line options; if the return value of* ParseArguments is false, the program should exit.*/// 解析参数if (!ParseArguments(&argc, &argv, &mode, &what, &ret, jrepath)){return(ret);}/* Override class path if -jar flag was specified */if (mode == LM_JAR) {SetClassPath(what);     /* Override class path */}/* set the -Dsun.java.command pseudo property */SetJavaCommandLineProp(what, argc, argv);/* Set the -Dsun.java.launcher pseudo property */SetJavaLauncherProp();/* set the -Dsun.java.launcher.* platform properties */SetJavaLauncherPlatformProps();
5.初始化jvm
return JVMInit(&ifn, threadStackSize, argc, argv, mode, what, ret);

JVMInit函数最后一句是

return ContinueInNewThread(ifn, threadStackSize, argc, argv, mode, what, ret);

继续看ContinueInNewThread函数,会进入ContinueInNewThread0函数

ContinueInNewThread0(JavaMain, threadStackSize, (void*)&args);

实现在新的线程中执行JavaMain函数

  1. 初始化虚拟机,如果报错直接退出。
/* Initialize the virtual machine */
start = CounterGet();
if (!InitializeJVM(&vm, &env, &ifn)) {JLI_ReportErrorMessage(JVM_ERROR1);exit(1);
}
  1. 加载主类
mainClass = LoadMainClass(env, mode, what);
  1. 获取Application Main Class

某些没有主方法的Java程序比如JavaFX应用,会获取Application Main Class

/** In some cases when launching an application that needs a helper, e.g., a* JavaFX application with no main method, the mainClass will not be the* applications own main class but rather a helper class. To keep things* consistent in the UI we need to track and report the application main class.*/
appClass = GetApplicationClass(env);
  1. 初始化完成
PostJVMInit(env, appClass, vm);
  1. 获取主类中的主方法
mainID = (*env)->GetStaticMethodID(env, mainClass, "main","([Ljava/lang/String;)V");

在字节码中void main(String[] args)表示为([Ljava/lang/String;)V

  1. 调用主方法
/* Invoke main method. */
(*env)->CallStaticVoidMethod(env, mainClass, mainID, mainArgs);
  1. LEAVE函数结束线程,销毁JVM
/** The launcher's exit code (in the absence of calls to* System.exit) will be non-zero if main threw an exception.*/
ret = (*env)->ExceptionOccurred(env) == NULL ? 0 : 1;
LEAVE();

流程图如下:
avatar

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/237476.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

centos7安装开源日志系统graylog5.1.2

安装包链接&#xff1a;链接&#xff1a;https://pan.baidu.com/s/1Zl5s7x1zMWpuKfaePy0gPg?pwd1eup 提取码&#xff1a;1eup 这里采用的shell脚本安装&#xff0c;脚本如下&#xff1a; 先使用命令产生2个参数代入到脚本中&#xff1a; 使用pwgen生成password_secret密码 …

在ClickHouse数据库中启用预测功能

在这篇博文中&#xff0c;我们将介绍如何将机器学习支持的预测功能与 ClickHouse 数据库集成。ClickHouse 是一个快速、开源、面向列的 SQL 数据库&#xff0c;对于数据分析和实时分析非常有用。该项目由 ClickHouse&#xff0c; Inc. 维护和支持。我们将探索它在需要数据准备以…

C++中多态的原理

文章目录 前言多态的原理多态的条件要求虚函数表用程序打印虚表多继承的虚函数表静态多态和动态多态菱形虚拟继承 前言 上篇讲解了多态的原理&#xff0c;这篇文章来详细讲解一下多态的原理。 这里有一道常考笔试题&#xff1a;sizeof(Base)是多少&#xff1f; 为什么不是8&…

【CF闯关练习】—— 800分段

&#x1f30f;博客主页&#xff1a;PH_modest的博客主页 &#x1f6a9;当前专栏&#xff1a;cf闯关练习 &#x1f48c;其他专栏&#xff1a; &#x1f534;每日一题 &#x1f7e1; C跬步积累 &#x1f7e2; C语言跬步积累 &#x1f308;座右铭&#xff1a;广积粮&#xff0c;缓…

推荐一个vscode看着比较舒服的主题:Dark High Contrast

主题名称&#xff1a;Dark High Contrast &#xff08;意思就是&#xff0c;黑色的&#xff0c;高反差的&#xff09; 步骤&#xff1a;设置→Themes→Color Theme→Dark High Contrast 效果如下&#xff1a; 感觉这个颜色的看起来比较舒服。

腾讯云发布升级版金融音视频解决方案,提供全新架构、安全和特性

远程银行、视频尽调、全媒体客服、路演直播……近年来&#xff0c;音视频技术支撑下的非接触式金融服务&#xff0c;成为了金融机构数字化转型和探索服务创新的重要方向。 12月21日&#xff0c;腾讯云正式发布升级版金融级音视频解决方案。新方案在架构、安全和特性上进行全面…

【数字图像处理】实验二 图像变换

图像变换 一、实验内容&#xff1a; 1&#xff0e; 熟悉和掌握利用Matlab工具进行数字图像的读、写、显示等数字图像处理基本步骤。 2&#xff0e; 熟练掌握各种图像变换的基本原理及方法。 3&#xff0e; 能够从深刻理解图像变换&#xff0c;并能够思考拓展到一定的应用领域。…

Ubuntu 常用命令之 less 命令用法介绍

&#x1f4d1;Linux/Ubuntu 常用命令归类整理 less命令是一个在Unix和Unix-like系统中用于查看文件内容的命令行工具。与more命令相比&#xff0c;less命令提供了更多的功能和灵活性&#xff0c;例如向前和向后滚动查看文件&#xff0c;搜索文本&#xff0c;查看长行等。 les…

ChatGPT一周年:开源语言大模型的冲击

自2022年末发布后&#xff0c;ChatGPT给人工智能的研究和商业领域带来了巨大变革。通过有监督微调和人类反馈的强化学习&#xff0c;模型可以回答人类问题&#xff0c;并在广泛的任务范围内遵循指令。在获得这一成功之后&#xff0c;人们对LLM的兴趣不断增加&#xff0c;新的LL…

阿里云ECS配置IPv6后,如果无法访问该服务器上的网站,可检查如下配置

1、域名解析到这个IPv6地址,同一个子域名可以同时解析到IPv4和IPv6两个地址&#xff0c;这样就可以给网站配置ip4和ipv6双栈&#xff1b; 2、在安全组规则开通端口可访问&#xff0c;设定端口后注意授权对象要特殊设置“源:::/0” 3、到服务器nginx配置处&#xff0c;增加端口…

Qt之QWidget 自定义倒计时器

简述 Qt提供的带进度显示的只有一个QProgresBar,这个控件要么是加载进度从0~100%,要么是持续的两边滚动;而我想要是倒计时的效果,所以QProgresBar并不满足要求,而Qt重写控件相对于MFC来说简直是轻而易举,所以就整了两种不同的倒计时控件; 效果 代码 QPushButton的绘制部…

2023 英特尔On技术创新大会直播 | AI魅力的生活化

目录 前言正文 前言 依稀记得去年的直播大会&#xff0c;主要展现了其灵活、加速和半集成化的独特优势&#xff0c;广泛应用于人工智能、5G通信、边缘计算以及视觉图像处理等领域&#xff0c;不断提供领先的性能、能效和可编程性的创新。 如今又带来一些不一样的特色&#xf…

通过U盘:将电脑进行重装电脑

目录 一.老毛桃制作winPE镜像 1.制作准备 2.具体制作 下载老毛桃工具 插入U盘 选择制作模式 正式配置U盘 安装提醒 安装成功 具体操作 二.使用ultrasio制作U盘 1.具体思路 2.图片操作 三.硬盘安装系统 具体操作 示例图 ​编辑 一.老毛桃制作winPE镜像 1.制作准…

【Pytorch】学习记录分享6——PyTorch经典网络 ResNet与手写体识别

【Pytorch】学习记录分享5——PyTorch经典网络 ResNet 1. ResNet &#xff08;残差网络&#xff09;基础知识2. 感受野3. 手写体数字识别3. 0 数据集&#xff08;训练与测试集&#xff09;3. 1 数据加载3. 2 函数实现&#xff1a;3. 3 训练及其测试&#xff1a; 1. ResNet &…

Bash 脚本学习

文章目录 1、脚本编程基础2. 变量2.1 参数变量的引用2.2 环境变量 3 条件判断语句3.1 if 语句3.1.1 语法3.1.2 案例 3.2 case 语句3.2.1 语法3.2.2 案例 3.3 判断参数说明 4 循环语句4.1 for 循环4.1.1 语法4.1.2 案例 4.2 while循环4.2.1 语法4.2.2 案例4. 3 循环总结 5. 函数…

Prompt-to-Prompt:基于 cross-attention 控制的图像编辑技术

Hertz A, Mokady R, Tenenbaum J, et al. Prompt-to-prompt image editing with cross attention control[J]. arXiv preprint arXiv:2208.01626, 2022. Prompt-to-Prompt 是 Google 提出的一种全新的图像编辑方法&#xff0c;不同于任何传统方法需要用户指定编辑区域&#xff…

微信小程序开发系列-01创建一个最小的小程序项目

本文讲述了通过微信开发者工具&#xff0c;创建一个新的小程序项目&#xff0c;完全从零开始&#xff0c;不依赖开发者工具的模板。目的是为了更好的理解小程序工程项目的构成。 文章目录 创建一个空项目app.json全局配置pagessitemapLocation app.js 创建一个空项目 打开微信…

新型智慧视频监控系统:基于TSINGSEE青犀边缘计算AI视频识别技术的应用

边缘计算AI智能识别技术在视频监控领域的应用有很多。这项技术结合了边缘计算和人工智能技术&#xff0c;通过在摄像头或网关设备上运行AI算法&#xff0c;可以在现场实时处理和分析视频数据&#xff0c;从而实现智能识别和分析。目前来说&#xff0c;边缘计算AI视频智能技术可…

aws-waf-cdn 基于规则组的永黑解决方案

1. 新建waf 规则组 2. 为规则组添加规则 根据需求创建不同的规则 3. waf中附加规则组 &#xff08;此时规则组所有规则都会附加到waf中&#xff0c;但是不会永黑&#xff09; 此刻&#xff0c;可以选择测试下规则是否生效&#xff0c;测试前确认保护资源绑定无误 4. 创建堆…

02 - Kbuild子系统(整理中)

1. Kbuild简介 Kernel build&#xff0c;用来编译 Linux 内核基于 GNU make 设计&#xff0c;对 Makefile 进行扩充 菜单式配置&#xff1a;Kconfig预定义目标和变量&#xff1a;xx_defconfig、menuconfig、obj-y跨平台工具、递归式 Makefile Linux 模块化设计、高度可以裁剪 …