jvm理解
创始人
2024-05-31 05:06:20
0

1.堆栈

JVM运行字节码时,所有的操作基本都是围绕两种数据结构,一种是堆栈(本质是栈结构),还有一种是队列,如果JVM执行某条指令时,该指令需要对数据进行操作,那么被操作的数据在指令执行前,必须要压到堆栈上,JVM会自动将栈顶数据作为操作数。如果堆栈上的数据需要暂时保持起来时,那么它就会被存储到局部变量队列上。

0: bipush        10     //0是程序偏移地址,然后是指令,最后是操作数
2: istore_1

这一步操作实际上就是使用bipush将10推向栈顶,接着使用istore_1将当前栈顶数据存放到第二个局部变量中,也就是a,所以这一步执行的是int a = 10操作。

3: bipush        20
5: istore_2

同上,这里执行的是int b = 20操作。

6: iload_1
7: iload_2
8: iadd

这里是将第二和第三个局部变量放到栈中,也就是取a和b的值到栈中,最后iadd操作将栈中的两个值相加,结果依然放在栈顶。

9: istore_3
10: iload_3
11: ireturn

将栈顶数据存放到第四个局部变量中,也就是c,执行的是int c = 30,最后取出c的值放入栈顶,使用ireturn返回栈顶值,也就是方法的返回值。至此,方法执行完毕。

实际上我们发现,JVM执行的命令基本都是入栈出栈等,而且大部分指令都是没有操作数的,传统的汇编指令有一操作数、二操作数甚至三操作数的指令,相比C编译出来的汇编指令,执行起来会更加复杂,实现某个功能的指令条数也会更多,所以Java的执行效率实际上是不如C/C++的,虽然能够很方便地实现跨平台,但是性能上大打折扣,所以在性能要求比较苛刻的Android上,采用的是定制版的JVM,并且是基于寄存器的指令集架构。在某些情况下,我们可以使用JNI机制来通过Java调用C/C++编写的程序以提升性能(也就是本地方法,使用到native关键字)

2.jvm启动流程:

 配置JVM装载环境-> 解析虚拟机参数- >设置线程栈大小->执行JavaMain方法

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版本

SelectVersion(argc, argv, &main_class);

3.创建合适的jvm执行环境,例如需要确定模型数据,32位还是64位,以及jvm本身的一些配置在jvm.config文件中读取和解析。

4.jvm初始化,有所在的平台进行

return JVMInit(&ifn, threadStackSize, argc, argv, mode, what, ret);

 3.内存管理

        Java只支持直接使用基本数据类型和对象类型,至于内存到底如何分配,并不是由我们来处理,而是JVM帮助我们进行控制,这样就帮助我们节省很多内存上的工作,虽然带来了很大的便利,但是,一旦出现内存问题,我们就无法像C/C++那样对所管理的内存进行合理地处理,因为所有的内存操作都是由JVM在进行,只有了解了JVM的内存管理机制,我们才能够在出现内存相关问题时找到解决方案。

3.1内存区域划分

 我们可以看到,内存区域一共分为5个区域,其中方法区和堆是所有线程共享的区域,随着虚拟机的创建而创建,虚拟机的结束而销毁,而虚拟机栈、本地方法栈、程序计数器都是线程之间相互隔离的,每个线程都有一个自己的区域,并且线程启动时会自动创建,结束之后会自动销毁。内存划分完成之后,我们的JVM执行引擎和本地库接口,也就是Java程序开始运行之后就会根据分区合理地使用对应区域的内存了。

程序计数器

        首先我们来介绍一下程序计数器,它和我们的传统8086 CPU中PC寄存器的工作差不多,因为JVM虚拟机目的就是实现物理机那样的程序执行。在8086 CPU中,PC作为程序计数器,负责储存内存地址,该地址指向下一条即将执行的指令,每解释执行完一条指令,PC寄存器的值就会自动被更新为下一条指令的地址,进入下一个指令周期时,就会根据当前地址所指向的指令,进行执行。

而JVM中的程序计数器可以看做是当前线程所执行字节码的行号指示器,而行号正好就指的是某一条指令,字节码解释器在工作时也会改变这个值,来指定下一条即将执行的指令。

因为Java的多线程也是依靠时间片轮转算法进行的,因此一个CPU同一时间也只会处理一个线程,当某个线程的时间片消耗完成后,会自动切换到下一个线程继续执行,而当前线程的执行位置会被保存到当前线程的程序计数器中,当下次轮转到此线程时,又继续根据之前的执行位置继续向下执行。

程序计数器因为只需要记录很少的信息,所以只占用很少一部分内存。

虚拟机栈

        虚拟机栈就是一个非常关键的部分,看名字就知道它是一个栈结构,每个方法被执行的时候,Java虚拟机都会同步创建一个栈帧(其实就是栈里面的一个元素),栈帧中包括了当前方法的一些信息,比如局部变量表、操作数栈、动态链接、方法出口等。

image-20220131110349472

         其中局部变量表就是我们方法中的局部变量,实际上局部变量表在class文件中就已经定义好了,操作数栈就是我们之前字节码执行时使用到的栈结构; 每个栈帧还保存了一个可以指向当前方法所在类的运行时常量池,目的是:当前方法中如果需要调用其他方法的时候,能够从运行时常量池中找到对应的符号引用,然后将符号引用转换为直接引用,然后就能直接调用对应方法,这就是动态链接(我们还没讲到常量池,暂时记住即可,建议之后再回顾一下),最后是方法出口,也就是方法该如何结束,是抛出异常还是正常返回。
 

public class Main {public static void main(String[] args) {int res = a();System.out.println(res);}public static int a(){return b();}public static int b(){return c();}public static int c(){int a = 10;int b = 20;return a + b;}
}

执行流程:

image-20220131142625842

 接着我们继续往下,到了0: invokestatic #2 // Method a:()I时,需要调用方法a(),这时当前方法就不会继续向下运行了,而是去执行方法a(),那么同样的,将此方法也入栈,注意是放入到栈顶位置,main方法的栈帧会被压下去:

image-20220131143641690

 这时,进入方法a之后,又继而进入到方法b,最后在进入c,因此,到达方法c的时候,我们的虚拟机栈变成了:

image-20220131144209743

 现在我们依次执行方法c中的指令,最后返回a+b的结果,在方法c返回之后,也就代表方法c已经执行结束了,栈帧4会自动出栈,这时栈帧3就得到了上一栈帧返回的结果,并继续执行,但是由于紧接着马上就返回,所以继续重复栈帧4的操作,此时栈帧3也出栈并继续将结果交给下一个栈帧2,最后栈帧2再将结果返回给栈帧1,然后栈帧1就可以继续向下运行了,最后输出结果。
image-20220131144955668

 

相关内容

热门资讯

全球城市科技传播能力指数202... 今天,上海交通大学文化创新与青年发展研究院首席专家徐剑教授团队在上海科技节·科技传播理论分会发布了《...
甘肃张掖:“宣讲+礼赞+关爱”... 来源:工人日报客户端 原标题:甘肃张掖:“宣讲+礼赞+关爱”开启劳模工匠风采宣传月工人日报-中工网记...
惊艳!老祖宗绣给你的绝美织锦壁... 老祖宗的审美高级感中国织物中对金线、金箔的运用,可追溯至战国时期。波光粼粼的织金锦缎,华美而不俗艳!...
尼山鲁源村景区将于5月31日盛... 官宣了!官宣了!尼山鲁源村景区将于5月31日盛大开园!尼山鲁源村位于山东曲阜是尼山圣境二期工程,以“...
云南举行国际护士节主题活动 来源:工人日报客户端 原标题:云南举行国际护士节主题活动工人日报-中工网记者 黄榆5月15日,云南省...
狂赚近百亿!光伏一季度,谁“翻... (转自:全球光伏)  2025年第一季度,光伏行业是喜忧参半!在行业周期下行期间,430和531两个...
【拔节生长看雄安】雄安未来之城... 转自:河北新闻网 冀时客户端报道 5月15日,雄安未来之...
内蒙古三位厅干拟“由政转企” 转自:上观新闻《内蒙古日报》消息,5月16日,内蒙古自治区党委组织部发布干部任前公示,其中三位厅干拟...
隆基、晶科、通威、晶澳、正泰、... (转自:全球光伏)  5月16日,《财富》中文网正式发布“2025年中国ESG影响力榜单”,隆基、阳...
【撸起袖子加油干 风雨无阻向前... 转自:河北新闻网 冀时客户端报道 以交通基础设施“硬联通...
山东移动发布四大云智宽带产品,... 转自:大众报业·齐鲁壹点5月17日,山东移动在济南举办“万兆智联 云启AI家”爱家计划暨云智宽带系列...
桂林三金:整体库存水平持续向好... 人民财讯5月17日电,桂林三金(002275)近日接受机构调研时表示,目前公司不仅实现自身库存的高效...
俄乌直接会谈 欧盟为何“唱反调... 转自:央视当地时间16日,俄乌在土耳其进行了直接会谈。同天,欧盟委员会主席冯德莱恩却表示,欧盟方面准...
6月1日起实施!吉林省执行10... 5月15日,吉林省医疗保障局发布通知,林下山参(生晒参)支付标准执行10元/克。林下山参费用可使用个...
百姓看联播丨氢能“大肺王” “... 转自:河北新闻网 这两年,路上的氢能卡车、公交车越来越多...
当地回应应县木塔持续倾斜:正评... #网友反映山西应县木塔持续倾斜#【#当地回应应县木塔持续倾斜#:正评估修护方案并1:1复原】近日,有...
小学生纠错,浙江文广旅厅长回信... 来源:人民网 近日 浙江省湖州市安吉县安城小学 五年级学生金陈乐收到了一封来自 浙江省文化广电和旅游...
探索“眼睛的奥秘” 青少年眼健... 为助力青少年科学护眼,普及眼健康知识,契合全国爱眼日来临之际,2025青少年眼健康知识挑战营将于5月...
黄莺:从特殊走向融合,从黑暗走... 编者按:5月16日,由国务院残疾人工作委员会办公室、中国残疾人联合会联合举办的第七次全国自强模范暨助...
中柬“金龙-2025”联演开幕 转自:北京日报客户端中柬“金龙-2025”联演开始仪式5月17日在柬埔寨磅清扬省王家军宪兵训练中心举...