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

tomcat有没有main函数

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

JVM的main函数

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

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

JAVAW 的启动头是

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的启动头是

JNIEXPORT int
main(int argc, char **argv)
{
    int margc;
    char** margv;
    int jargc;
    char** jargv;
    const jboolean const_javaw = JNI_FALSE;

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

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行,有如下代码:

if (printVersion || showVersion) {
    PrintJavaVersion(env, showVersion);
    CHECK_EXCEPTION_LEAVE(0);
    if (printVersion) {
        LEAVE();
    }
}

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

其实现如下:

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虚拟机启动的过程. 这部分是后面的基础, 希望小伙伴们能跟着小刀一起,落实这方面的知识,加油!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值