首页
学习
活动
专区
工具
TVP
发布

JVM系列(二):jvm是如何加载java代码的?

上一篇粗略讲了下jvm的启动过程,但很多路子还没跑通。其中非常核心的,加载vm的过程。这个可以在hotspot中找到端倪。但jvm启动,又是如何载入java代码呢。

1. JavaMain加载流程

我们知道,java中入口是在main方法中,可以在命令行中指定main类,或者jar包中指定的manifest.xml中指定的main类。在java.c中,我们可以看到一个JavaMain方法,不知从何而来,但很像是直接加载java入口的方法。

略去核心加载jvm的实现,要加载main类,还是比较简单的。主要就是通过前面查找出的main_class, 然后通过在jvm的实例中获取到的各方法的函数指针,然后按照字节码的规范,调用 MainClass.main(String[]) 方法。当然了,为了兼容其他非main的场景,它还有很多附加处理逻辑。

另外,如何翻译java代码,并执行,这是jvm的重中之重。即编译原理的拿手好戏,也是我们普通程序员越不过的坎!但至少,我们来到了门槛前面!

2. jvm启动框架

前面讲了加载main方法的过程,大致理解了c如何启动调用java的main的。那么,这又是如何调用准备的呢,在这之前都需要做哪些准备呢?

实际上,这是平台相关的实现。

以上是mac调用 javaMain的方式。在windows, 以及linux上则稍有不同。

在linux中的创建线程如下:

即相同的语义,不同平台下的各自实现而已。

通过C语言的函数传递,从而进行调用。通过创建一个新线程,调用JavaMain(); 由javaMain处理所有java事务。而自身则只需等待JavaMain完成即可。这也符合面向过程编程思想。

3. jvm初始化小结

我们平时是通过 java xxx.xxx  或者 java -jar xx.jar 启动jvm, 通过这两篇文章,我们也看清了其背后的原理。就是通过解析各种参数,验证各种参数,验证jre环境,然后验证jre是否可用,最后将指定的mainClass加载出来。丢到一个新的线程中去执行,将执行权力转发给java代码,最后等待该线程完成。

应该说事个流程没有难点,或者说一切都很理所当然。但其中的核心,都是通过加载JavaVM()去做的,也就是真正的jvm. 然后通过或者对应的几个接口方法地址,进行调用,从而完成启动任务。所以,java虽是一个启动命令,但核心并不在这里。而是在 hotspot 或其他地方。jdk 毕竟只是一个工具箱而已。jre 才是关键。

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20210222A01BQH00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券