2000字范文,分享全网优秀范文,学习好帮手!
2000字范文 > JVM内存模型和性能调优:栈(线程)- 第11篇

JVM内存模型和性能调优:栈(线程)- 第11篇

时间:2018-12-03 00:15:05

相关推荐

JVM内存模型和性能调优:栈(线程)- 第11篇

前言

栈是线程运行的单位,那接下我们不会讲太多概念性的东西,主要是通过Math.java这个类和大家分析学习。

一、线程栈分析

我们看下Math.java类:

public class Math {public static int initData = 666;public int compute(){//int a = 1;int b = 2;int c = (a+b)*10;return c;}public static void main(String[] args) {Math math = new Math();int rs = pute();System.out.println(rs);}}

由于main方法是主线程,JVM会为每个线程都分配一个栈的内存空间,一个方法对应一块栈帧内存区域。

首先为main()方法分配一块栈帧内存区域,入栈:

当执行到pute()的时候,为compute()方法分配一块栈帧内存区域:

在每个栈帧中有这么几个概念:局部变量、操作数栈、动态链接、方法出口。

我们以compute()方法中的代码进行讲解:

public int compute(){//一个方法对应一块栈帧内存区域int a = 1;int b = 2;int c = (a+b)*10;return c;}

这里先看两个概念局部变量和操作数栈,这也是两块内存空间。

在变量的内存空间第一个位置的指向是this。

接下来我们借助一个指令来进行学习:javap -c Math.class

这是将二进制反编译为更可读的jvm指令码,我们看下compute()的代码:

这指令码是什么意思呢?

这里整理了一个对应表:

/ynoteshare1/index.html?id=fd46a7566fe897abb8db5b25fa0accdf&type=note

Code 0:iconst_1 : 将int类型常量1压入操作数栈

Code 1:istore_1 : 将栈顶int型数值存入第二个本地变量

说明:int型数值1从操作数栈出栈,然后存如第二个本地变量,此时a=1;

Code 2: iconst_2 : 将int型(2)推送至栈顶

Code 3: istore_2 : 将栈顶int型数值存入第三个本地变量

到这里我们了解下程序计数器,对于内存模型不是独立的,需要整体理解,我们简单理解程序计算器就是代码执行的行号(实际上应该是内存的句柄或者指针),对于程序计算器也是一块内存空间,是有字节码执行引擎进行操作的。

Code 4: iload_1:将第二个int型本地变量推送至栈顶

Code 5: iload_2 : 将第三个int型本地变量推送至栈顶

Code 6: iadd :将栈顶两int型数值相加并将结果压入栈顶

将操作数栈的值拿出来进行iadd计算,得到3,在压入栈顶:

Code 7: bipush 10 : 将单字节的常量值(-128~127)推送至栈顶,这里就是10:

Code 9: imul : 将栈顶两int型数值相乘并将结果压入栈顶:

将操作数栈的两个数值取出进行imul计算得到30,并且压入栈顶:

Code 10: istore_3 : 将栈顶int型数值存入第四个本地变量

Code 11: iload_3 : 将第四个int型本地变量推送至栈顶。

这里就是将局部变量数值30推送操作数栈栈顶。

Code 12: ireturn : //从当前方法返回int

就是讲栈顶的数值取出进行返回。

接下来我们看下动态链接和方法出口:

动态链接比较复杂,我们之后在讲,我们看下方法出口,方法出口存储的就是方法执行完成之后需要返回的那个位置:

分析我们的代码方法出口就是指向了int rs = pute()这个地址了。

接下来我们看下main()方法的math局部变量,这个一个引用类型变量,那么它是这样子的:

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。