承接上一谈

OpenJDK源码赏析之一:漫谈java的历史渊源_星空_AZ的博客-CSDN博客

JAVA从启动到第一个函数执行的发生的流程:

WinMain->JLI_Launch->JVMInit->NewThread->JavaMain->initializateJVM->CreatJavaVM->LoadMainClass->GetStaticMethodID

看一个程序首先要找它的启动入口

OpenJDK的如下目录有着main程序的启动入口:

打开后是程序的入口,main的函数如下:

int WINAPI
WinMain(HINSTANCE inst, HINSTANCE previnst, LPSTR cmdline, int cmdshow)
{int margc;char** margv;const jboolean const_javaw = JNI_TRUE;__initenv = _environ;#else /* JAVAW */
int
main(int argc, char **argv)
{int margc;char** margv;const jboolean const_javaw = JNI_FALSE;
#endif /* JAVAW */
#ifdef _WIN32{int i = 0;if (getenv(JLDEBUG_ENV_ENTRY) != NULL) {printf("Windows original main args:\n");for (i = 0 ; i < __argc ; i++) {printf("wwwd_args[%d] = %s\n", i, __argv[i]);}}}JLI_CmdToArgs(GetCommandLine());margc = JLI_GetStdArgc();// add one more to mark the endmargv = (char **)JLI_MemAlloc((margc + 1) * (sizeof(char *)));{int i = 0;StdArg *stdargs = JLI_GetStdArgs();for (i = 0 ; i < margc ; i++) {margv[i] = stdargs[i].arg;}margv[i] = NULL;}
#else /* *NIXES */margc = argc;margv = argv;
#endif /* WIN32 */return JLI_Launch(margc, margv,sizeof(const_jargs) / sizeof(char *), const_jargs,sizeof(const_appclasspath) / sizeof(char *), const_appclasspath,FULL_VERSION,DOT_VERSION,(const_progname != NULL) ? const_progname : *margv,(const_launcher != NULL) ? const_launcher : *margv,(const_jargs != NULL) ? JNI_TRUE : JNI_FALSE,const_cpwildcard, const_javaw, const_ergo_class);
}

可以看到最后运行一个JLI_Launch的函数,JLI的全称为Java Native Interface,是java调用非java代码的接口,这个函数在java.c中,  找到java.c中该函数的位置

看到 CreateExecutionEnvironment,为创建执行环境

跳转到该函数实现位置

其实现了以下几个功能

①判断环境为32位或者64位

②得到JRE的路径

③ReadKnownVms()得到JVM.cfg文件(该文件为java的配置文件)

④CheckJvmType确认当前的jvm类型

⑤GetJVMPath根据上一步确定的JVM类型,找到对应的JVM.dll文件

继续回到java.c中的JLI_Launch函数,下面执行LoadJavaVM

跳转到该函数其实现了加载dll库,并绑定函数可以调用dll中的

LoadLibrary链接到DLL库(LoadLibrary为加载动态链接库),此库为jvm.dll

把JVM.dll文件中定义的函数JNI_CreateJavaVM和JNI_GetDefaultJavaVMInitArgs的指针绑定到InvocationFunctions变量的CreateJavaVM和GetDefaultJavaVMInitArgs函数指针变量上;

当装载好虚拟机所需要的环境之后,回到JLI_Launch函数最后一步要执行的JVMInit

跳转到JVMInit后,开始通过ContinueInNewThread创建新的Java进程

在ContinueInNewThread下有个函数ContinueInNewThread0​​​​​​​,执行了当前的主方法JavaMain

在JavaMain中有一个InitializeJVM

初始化虚拟机

/** Initializes the Java Virtual Machine. Also frees options array when* finished.*/
static jboolean
InitializeJVM(JavaVM **pvm, JNIEnv **penv, InvocationFunctions *ifn)
{JavaVMInitArgs args;jint r;memset(&args, 0, sizeof(args));args.version  = JNI_VERSION_1_2;args.nOptions = numOptions;args.options  = options;args.ignoreUnrecognized = JNI_FALSE;if (JLI_IsTraceLauncher()) {int i = 0;printf("JavaVM args:\n    ");printf("version 0x%08lx, ", (long)args.version);printf("ignoreUnrecognized is %s, ",args.ignoreUnrecognized ? "JNI_TRUE" : "JNI_FALSE");printf("nOptions is %ld\n", (long)args.nOptions);for (i = 0; i < numOptions; i++)printf("    option[%2d] = '%s'\n",i, args.options[i].optionString);}r = ifn->CreateJavaVM(pvm, (void **)penv, &args);JLI_MemFree(options);return r == JNI_OK;
}

最后有CreatJavaVM,初始化虚拟机

最后创建Java虚拟机进程后,回到JavaMain函数下面有这么一行:

把mainClass赋值为我们写的调用的主函数,以下为LoadMainClass源码

/** Loads a class and verifies that the main class is present and it is ok to* call it for more details refer to the java implementation.
* 加载一个类并验证主类是否存在,可以调用它以获取更多详细信息,请参阅java实现。*/static jclass
LoadMainClass(JNIEnv *env, int mode, char *name)
{jmethodID mid;jstring str;jobject result;jlong start, end;jclass cls = GetLauncherHelperClass(env);NULL_CHECK0(cls);if (JLI_IsTraceLauncher()) {start = CounterGet();}NULL_CHECK0(mid = (*env)->GetStaticMethodID(env, cls,"checkAndLoadMain","(ZILjava/lang/String;)Ljava/lang/Class;"));str = NewPlatformString(env, name);result = (*env)->CallStaticObjectMethod(env, cls, mid, USE_STDERR, mode, str);if (JLI_IsTraceLauncher()) {end   = CounterGet();printf("%ld micro seconds to load main class\n",(long)(jint)Counter2Micros(end-start));printf("----%s----\n", JLDEBUG_ENV_ENTRY);}return (jclass)result;
}

mainClass赋值完成以后,返回JavaMain函数接着执行下面的操作:

用CallStaticVoidMethod调用我们在Java里面写的Java入口函数mainClass

至此从java启动到运行第一个类的全逻辑已经理了一遍

想知道在命令行中输入java -help的流程吗,我将在下一篇将分析cmd下java命令行的读取

OpenJDK源码赏析之三:cmd下Java命令参数的读取_星空_AZ的博客-CSDN博客

OpenJDK源码赏析之二:java虚拟机启动流程到首函数调用全流程相关推荐

  1. OpenJDK源码赏析之三:Java命令参数的读取处理流程

    承接上一篇 OpenJDK源码赏析之二:java虚拟机启动流程到首函数调用全流程_星空_AZ的博客-CSDN博客 这篇这要解析Java虚拟机创建时候配置读取时候命令行参数的读取过程,这次采取逆向思维分 ...

  2. OpenJDK源码赏析之四(jli_util中的工具函数)

    上一篇: OpenJDK源码赏析之三:Java命令参数的读取_星空_MAX的博客-CSDN博客 不承接上一篇,这篇单独开始分析jli_util.h(java工具函数)里的一些函数 JLI_MemAll ...

  3. eos源码赏析(二十三):默克尔树在EOS中的应用(上)

    前面文章中在分析push_transactioneos源码赏析(二十):EOS智能合约之push_transaction的天龙八"步"以及区块签名eos源码赏析(二十一):EOS智 ...

  4. Java接入PayPal教程,Spring boot Demo源码,企业账号注册,支付,回调,退款全流程,最新PayPal SDK

    一.环境准备 1. 注册 2. 创建沙箱测试账号 3. Client ID及Secret 二.核心代码 1. 官方github sdk 2. pom引用 3. 代码讲解 4. 支付代码demo流程 5 ...

  5. Java虚拟机(JVM源码):编译OpenJDK源码

    为什么要自己编译JDK源码 作为一个搞技术的同学,如果想在技术这条路上走下去,还是多研究些本质性的东西,修炼下内功.尤其是现在JDK都出到10了,如果你没有研究过,还是停留在之前的时代,那么确实说不过 ...

  6. Java虚拟机启动整体流程和基础学习(内容很多,不可快餐阅读),推理+源码论证

    不啰嗦,直接看: ISA指令强关联CPU平台,那么汇编语言也一定强关联CPU平台,而C语言又是对汇编最简单的抽象,也就一定会耦合不同CPU平台的代码,这也就是意味着,在写C/C++项目的时候,必须要考 ...

  7. commons-math3-3.6.1-org.apache.commons.math3.analysis.function-包下的类(二)-中英对照文档及源码赏析

    commons-math3-3.6.1-org.apache.commons.math3.analysis.function-包下的类(二)-中英对照文档及源码赏析 摘要:中英对照文档.源码赏析.or ...

  8. java 官网下载jdk源码_openJDK之如何下载各个版本的openJDK源码

    如果我们需要阅读openJDK的源码,那么需要下载,那么该去哪下载呢? 现在JDK已经发展到版本10了,11已经处于计划中,如果需要特定版本的openJDK,它们的下载链接在哪呢? 1.openJDK ...

  9. jdk下没有java源码_openJDK之如何下载各个版本的openJDK源码

    如果我们需要阅读openJDK的源码,那么需要下载,那么该去哪下载呢? 现在JDK已经发展到版本10了,11已经处于计划中,如果需要特定版本的openJDK,它们的下载链接在哪呢? 1.openJDK ...

最新文章

  1. android 代码混淆 gson,Android RecyclerView和Gson混淆问题
  2. PingingLab传世经典系列《CCNA完全配置宝典》-3.2 VLAN进阶配置
  3. java 过滤攻击报文_Spring Boot XSS 攻击过滤插件使用
  4. 四则运算关于加括号的思路
  5. 使用 ADO.NET连接SQL Azure
  6. Web 学习之跨域问题及解决方案
  7. @Aspect @around 多个参数
  8. php mysql zend linux,Linux系统安装配置PHP+MySQL+zend+PHPadmin开发环境
  9. [py][mx]django分页第三方模块django-pure-pagination
  10. POJ1338 amp; POJ2545 amp; POJ2591 amp; POJ2247 找给定规律的数
  11. laravel常用拓展库
  12. jxta-amalto
  13. 英语字母演变——wsdchong
  14. python可视化——matplotlib画图颜色控制
  15. 喜欢《花样少年少女》
  16. DTV 学习(二) 数字视频
  17. 网页设计期末结课作业 2022最后的作业 用Dw div+css 做网页设计
  18. 第二次作业——结对项目之需求分析与原型设计
  19. matlab院校,MATLAB要来了?!
  20. Android中导航栏之自定义导航布局

热门文章

  1. Django 链接sqlserver 简单教程
  2. C++,OpenCV 中template(模板)的简单理解
  3. AFEPack 使用 Tutorial(二):解带系数二维泊松方程
  4. 堆外缓存是什么? OHC 堆外缓存使用简介
  5. WPS表格取消隐藏行不管用?
  6. 【SeedLab】Packet Sniffing and Spoofing Lab
  7. python中的颜色_Python学习第234课——html中的颜色值
  8. 《蜂鸟摄影学院单反摄影宝典》读书笔记
  9. 到底什么是上下文(Context)
  10. 你为什么总是很忙碌,却还在原地踏步!