前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >JVM | JVM的启动及java -version的执行过程

JVM | JVM的启动及java -version的执行过程

作者头像
微笑的小小刀
发布2020-02-17 13:55:59
8910
发布2020-02-17 13:55:59
举报
文章被收录于专栏:java技术大本营java技术大本营

tomcat有没有main函数

在学启动的时候, 我一直在想一个以前的java问题,就是Tomcat有没有Main函数, 答案肯定是有! 那么jvm做为一个C++应用程序, 他也肯定有man函数, 我们坚定这一点, 然后再去看代码

JVM的main函数

我们可以通过全局搜索可以定位到main函数的位置,如下图所示:

点进去文件可以看到jvm对不同的处理器32位/64位和不同的启动类型javaw/java做不了同的处理.

JAVAW 的启动头是

代码语言:javascript
复制
int WINAPI
WinMain(HINSTANCE inst, HINSTANCE previnst, LPSTR cmdline, int cmdshow)
{
    int margc;
    char** margv;
    int jargc;
    char** jargv;
    const jboolean const_javaw = JNI_TRUE;


    __initenv = _environ;

java的启动头是

代码语言:javascript
复制
JNIEXPORT int
main(int argc, char **argv)
{
    int margc;
    char** margv;
    int jargc;
    char** jargv;
    const jboolean const_javaw = JNI_FALSE;

往下的方法体中可以看到大都是对参数进行的处理, 直到这个文件的最后,开始Launch启动

代码语言:javascript
复制
return JLI_Launch(margc, margv,
               jargc, (const char**) jargv,
               0, NULL,
               VERSION_STRING,
               DOT_VERSION,
               (const_progname != NULL) ? const_progname : *margv,
               (const_launcher != NULL) ? const_launcher : *margv,
               jargc > 0,
               const_cpwildcard, const_javaw, 0)

该方法的实现是在src/java.base/share/native/libjli/java.c 这个目录下

在这个方法中, 我们可以看到, 主要是以下几步:

调用方法CreateExecutionEnvironment 创建运行环境

调用方法LoadJavaVM 去加载libjvm

调用方法ParseArguments 去解析参数

最后调用JVMInit 去启动JVM

JVMInit

这个方法就跟操作系统有关了,如下图所示不同的系统会去执行不同的文件的中代码

在对应系统的JVMInit的方法中, 会调用java.c 中的ContinueInNewThread方法,并在方法ContinueInNewThread 中调用不同操作系统的ContinueInNewThread0方法,如下图所示:

这样我们就来到了第一天,用Clion调试JDK源码时的JavaMain方法

JavaMain 方法

这里还是以打印版本号为例,可以看到在444行,有如下代码:

代码语言:javascript
复制
if (printVersion || showVersion) {
    PrintJavaVersion(env, showVersion);
    CHECK_EXCEPTION_LEAVE(0);
    if (printVersion) {
        LEAVE();
    }
}

可知实际调用的是PrintJavaVersion(env,showVersion)这个方法.

其实现如下:

代码语言:javascript
复制
static void
PrintJavaVersion(JNIEnv *env, jboolean extraLF)
{
    jclass ver;
    jmethodID print;
    // 找到指定的类
    NULL_CHECK(ver = FindBootStrapClass(env, "java/lang/VersionProps"));
    // 找到指定的方法
    NULL_CHECK(print = (*env)->GetStaticMethodID(env,
                                                 ver,
                                                 (extraLF == JNI_TRUE) ? "println" : "print",
                                                 "(Z)V"
                                                 )
              );
    // 调用这个方法
    (*env)->CallStaticVoidMethod(env, ver, print, printTo);
}

我们在Idea中,引入11的JDK , 然后就可以看到对应的输出

总结

至此,java -version的执行过程,我们是已经了解了, 而且借着java -version 我们还了解到了jvm虚拟机启动的过程. 这部分是后面的基础, 希望小伙伴们能跟着小刀一起,落实这方面的知识,加油!

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-01-20,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 java技术大本营 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • tomcat有没有main函数
  • JVM的main函数
  • JVMInit
  • JavaMain 方法
  • 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档