JVM启动流程(JDK8)

news2024/11/23 12:10:11

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.coloradmin.cn/o/1327345.html

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

相关文章

React-Native环境搭建(IOS)

系列文章目录 React-Native环境搭建&#xff08;IOS&#xff09; 目录 系列文章目录前言一、IOS环境搭建前置说明二、环境搭建步骤1.Homebrew安装2.安装Xcode3.Node4.watchman5.CocoaPods 三、项目启动1.初始化项目2.项目启动 总结 前言 React-Native开发环境的搭建&#xff…

Educational Codeforces Round 160 (Rated for Div. 2) A~C

目录 A. Rating Increase 题目分析&#xff1a; B. Swap and Delete 题目分析: C. Game with Multiset 题目分析: A. Rating Increase 题目分析&#xff1a; 因为首部不为零&#xff0c;故我们从第二个字符开始遍历&#xff0c;如果遇到第一个不为‘0’的字符&#xff0…

Jupyter Notebook修改默认工作目录

1、参考修改Jupyter Notebook的默认工作目录_jupyter文件路径-CSDN博客修改配置文件 2.在上述博客内容的基础上&#xff0c;这里不是删除【%USERPROFILE%】而是把这个地方替换为所要设置的工作目录路径&#xff0c; 3.【起始位置】也可以更改为所要设置的工作目录路径&#x…

Unity中的导航系统

NavMesh(导航网格)是3D游戏世界中用于实现动态物体自动寻路的一种技术&#xff0c;将游戏中复杂的结构组织关系简化为带有一定信息的网格&#xff0c;在这些网格的基础上通过一系列的计算来实现自动寻路。导航时&#xff0c;只需要给导航物体挂载导航组建&#xff0c;导航物体便…

树莓派,opencv,Picamera2利用舵机云台追踪特定颜色对象(PID控制)

一、需要准备的硬件 Raspiberry 4b两个SG90 180度舵机&#xff08;注意舵机的角度&#xff0c;最好是180度且带限位的&#xff0c;切勿选360度舵机&#xff09;二自由度舵机云台&#xff08;如下图&#xff09;Raspiberry CSI 摄像头 组装后的效果&#xff1a; 二、项目目标…

uni-app ucharts中饼图与圆环图区别

项目情况&#xff1a; uni-app的用于移动端H5项目&#xff0c;包使用uni_modules目录存放。 图表引用ucharts中的echarts配置的组件方式 区别1 饼图与圆环图在echarts使用的配置都是pie类型。但是配置raduis使用&#xff1a; radius: [40%, 70%] 区别2 组件type指明&#xf…

nodejs连接mongodb报错SyntaxError: Unexpected token .

nodejs连接mongodb报错SyntaxError: Unexpected token 如下图 经过排查&#xff0c;原因是npm默认安装的mongodb插件是最新版6.3.0 &#xff0c;而mongodb数据库版本是4.0.0 &#xff0c;两者版本不同导致nodejs报错。 解决方法是npm卸载新版本的mongodb插件&#xff0c;再安…

安卓加载项目gradle下载慢

更换镜像源 distributionUrlhttps://mirrors.cloud.tencent.com/gradle//gradle-5.6.4-all.zip

个人财务工具、密钥管理平台、在线会计软件、稍后阅读方案 | 开源专题 No.51

gethomepage/homepage Stars: 10.1k License: GPL-3.0 这个项目是一个现代化、完全静态的、快速且安全的应用程序仪表盘&#xff0c;具有超过 100 种服务和多语言翻译的集成。 快速&#xff1a;网站在构建时以静态方式生成&#xff0c;加载时间飞快。安全&#xff1a;所有对后…

万德高科携手航天科技AIRIOT打造智慧能碳管理平台, 助力碳达峰碳中和

“十四五”时期&#xff0c;我国生态文明建设进入了以降碳为重点战略方向、推动减污降碳协同增效、促进经济社会发展全面绿色转型、实现生态环境质量改善由量变到质变的关键时期。“实施数字化赋能行动”&#xff0c;聚焦能源管理、节能降碳、低碳能力等典型场景&#xff0c;推…

RAG实战案例:如何基于 LangChain 实现智能检索生成系统

在人工智能领域&#xff0c;如何有效结合大型语言模型&#xff08;LLM&#xff09;的常识性知识与特定的专有数据&#xff0c;一直是业界探索的热点。微调&#xff08;Fine-tuning&#xff09;与检索增强生成&#xff08;Retrieval-Augmented Generation&#xff0c;简称RAG&am…

5 分钟内搭建一个免费问答机器人:Milvus + LangChain

搭建一个好用、便宜又准确的问答机器人需要多长时间&#xff1f; 答案是 5 分钟。只需借助开源的 RAG 技术栈、LangChain 以及好用的向量数据库 Milvus。必须要强调的是&#xff0c;该问答机器人的成本很低&#xff0c;因为我们在召回、评估和开发迭代的过程中不需要调用大语言…

[SWPUCTF 2021 新生赛]Do_you_know_http已

打开环境 它说用WLLM浏览器打开&#xff0c;使用BP抓包&#xff0c;发送到重发器 修改User-Agent 下一步&#xff0c;访问a.php 这儿他说添加一个本地地址&#xff0c;它给了一个183.224.40.160&#xff0c;我用了发现没用&#xff0c;然后重新添加一个地址&#xff1a;X-Forwa…

3. 行为模式 - 迭代器模式

亦称&#xff1a; Iterator 意图 迭代器模式是一种行为设计模式&#xff0c; 让你能在不暴露集合底层表现形式 &#xff08;列表、 栈和树等&#xff09; 的情况下遍历集合中所有的元素。 问题 集合是编程中最常使用的数据类型之一。 尽管如此&#xff0c; 集合只是一组对象的…

将qt程序注册成服务

将qt程序注册成服务 1、qt服务模块管理下载 qt-solutions 2、QtService项目 2.1、将qtservice拷贝到项目代码路径 2.2、实现服务管理 PS&#xff1a;响应服务的启停 CustomService.h #include <QCoreApplication> #include "qtservice.h"class CustomSer…

React网页转换为pdf并下载|使用jspdf html2canvas

checkout 分支后突然报错&#xff0c;提示&#xff1a; Cant resolve jspdf in ... Cant resolve html2canvas in ... 解决方法很简单&#xff0c;重新 yarn install 就好了&#xff0c;至于为什么&#xff0c;我暂时也不知道&#xff0c;总之解决了。 思路来源&#xff1a; 先…

opencv静态链接error LNK2019

opencv 3.1.0 静态库&#xff0c;包括以下文件 只链接opencv_world310d.lib&#xff0c;报错 opencv_world310d.lib(matrix.obj) : error LNK2019: 无法解析的外部符号 _ippicvsFlip_16u_I8&#xff0c;该符号在函数 "enum IppStatus (__stdcall*__cdecl cv::getFlipFu…

安全狗云原生安全-云甲·云原生容器安全管理系统

随着云计算的快速发展&#xff0c;容器技术逐渐成为主流。然而&#xff0c;随着容器的普及&#xff0c;安全问题也日益突出。为了解决这一问题&#xff0c;安全狗推出了云原生容器安全管理系统——云甲。 云甲是安全狗云原生安全的重要组成部分&#xff0c;它采用了先进的云原生…

深入了解Spring MVC工作流程

目录 1. MVC架构简介 2. Spring MVC的工作流程 2.1. 客户端请求的处理 2.2. 视图解析和渲染 2.3. 响应生成与返回 3. Spring MVC的关键组件 3.1. DispatcherServlet 3.2. HandlerMapping 3.3. Controller 3.4. ViewResolver 4. 结论 Spring MVC&#xff08;Model-Vi…

【Midjourney】Midjourney根据prompt提示词生成黑白色图片

目录 &#x1f347;&#x1f347;Midjourney是什么&#xff1f; &#x1f349;&#x1f349;Midjourney怎么用&#xff1f; &#x1f514;&#x1f514;提示词格式 &#x1f34b;&#x1f34b;应用示例——“秘密花园”式涂色书配图生成 &#x1f34c;&#x1f34c;例子1…