JVM分析
来源:互联网 发布:电商淘宝培训 编辑:程序博客网 时间:2024/06/05 16:30
本文地址:JVM分析
- 关于JVM执行模型。Java虚拟机(JVM)是基于栈结构的,也就是Java代码运行在Java虚拟机线程中,而每一个线程拥有多个执行栈,执行栈由多个帧组成,每执行一个方法,则在执行栈中产生一个帧,即方法被触发时,一个新产生的帧将被Push到当前线程的执行栈中,当该方法执行完毕正常返回或者发生异常时,该帧将被Pop出执行栈。
- 关于帧。每个帧由本地变量(Local Variables)和操作栈(Operand Stack)两部分组成。
变量
局部变量
java
int i=5;
被编译成:
java
0: bipush 5
2: istore_0
内存中转换情况:
成员变量
public class SimpleClass { public int simpleField = 100;}
被编译成;
public SimpleClass(); Code: stack=2, locals=1, args_size=1 0: aload_0 1: invokespecial #1 //调用Object的init构造方法 4: aload_0 5: bipush 100 7: putfield #2 //成员变量simpleField` 类型为int整型 10: return
条件选择
if-else
public int greaterThen(int intOne, int intTwo) { if (intOne > intTwo) { return 0; } else { return 1; }}
该方法会编译成以下字节码:
0: iload_11: iload_22: if_icmple 75: iconst_06: ireturn7: iconst_18: ireturn
首先使用iload_1和iload_2将两个参数加载到操作栈中,然后使用if_Icomple比较操作栈顶的两个值大小,如果intOne小于intTwo,则跳转到位置7,否则继续。
if_icomple:比较栈顶两个int值大小,小于或等于0时跳转
ireturn:从当前方法返回int
注:
iconst_0表示将int类型的0 push进操作栈,该组还有其他类型的操作指令
示例2:
public int greaterThen(float floatOne, float floatTwo) { int result; if (floatOne > floatTwo) { result = 1; } else { result = 2; } return result;}
编译成的字节码:
0: fload_1 1: fload_2 2: fcmpl 3: ifle 11 6: iconst_1 7: istore_3 8: goto 1311: iconst_212: istore_313: iload_314: ireturn
- fload_1和fload_2将参数推送至栈顶
- fcmpl:比较栈顶两个float类型值大小,将结果(1、0、-1)推送栈顶。若有一个数值为NaN,将-1推送栈顶
- ifle:栈顶int值小于0跳转
- istore_3:将栈顶int值传入第三个本地变量
Switch
switch表达式支持char、byte、short、int、string或enum类型,JVM对于Switch提供了两个指令:tableswitch以及lookupswitch,它们都支持对int值进行操作,而char、byte、short以及enum都可以在内部转换成为int。
- tableswitch:用于switch条件跳转,case值连续
- lookupswitch:用于switch条件跳转,case值不连续
tableswitch
tableswitch是列出最大值与最小值之间所有的case值(不管它是否出现在Java代码中),如果JVM发现switch变量不在最值范围内,则直接跳转到default代码块,在最值范围内,如果出现在代码中,则跳转到相应位置,若没有出现在代码块中,跳转到default处。它可以保证最值范围内每个case值都有相应的结果。
示例:
public int simpleSwitch(int intOne) { switch (intOne) { case 0: return 3; case 1: return 2; case 4: return 1; default: return -1; }}
被编译成:
0: iload_1 1: tableswitch { default: 42 min: 0 max: 4 0: 36 1: 38 2: 42 3: 42 4: 40 }36: iconst_337: ireturn38: iconst_239: ireturn40: iconst_141: ireturn42: iconst_m143: ireturn
这里tableswitch有0、1和4三个值,每个值对应了相应的代码块,同时还包含了最值范围内其他的值2和3,不过他们不是需要寻找的case值,所以指向了default处。
当指令执行时,首先判断是否在最值内,如果不在则直接转到default(default索引总是出现在第一个字节)处,如果她在最值中,则依次寻找满足的条件跳转到相应的位置。
lookupswitch
如果最值范围太大,而case值很稀疏,那么tableswitch则会消耗很多内存。此时使用lookupswitch更好,它只会列出对应的case值的跳转,而不是每一个介于最值间的跳转。
示例:
public int simpleSwitch(int intOne) { switch (intOne) { case 10: return 1; case 20: return 2; case 30: return 3; default: return -1; }}
被编译成:
0: iload_1 1: lookupswitch { default: 42 count: 3 10: 36 20: 38 30: 40 }36: iconst_137: ireturn38: iconst_239: ireturn40: iconst_341: ireturn42: iconst_m143: iretur
这里为了保证算法的性能,索引匹配的值是有序的。
循环
While循环
示例:
public void whileLoop() { int i = 0; while (i < 2) { i++; }}
0: iconst_0 1: istore_1 2: iload_1 3: iconst_2 4: if_icmpge 13 7: iinc 1, 110: goto 213: return
- iconst_0:将int型0放入操作栈
- istore_1:将操作栈顶0存入本地变量
- iload_1:将第二个本地变量推送至栈顶
- iconst_2:将int型2推送至栈顶
- if_icmpge:比较栈顶两个int型值大小,结果大于0时跳转(此时如果栈底大于栈顶值,则跳出while循环,转到13步,直接return)
- iinc:将指定int型变量增加指定值,这里iinc 1,1:在局部变量表第一个值加1
for循环
for循环与while循环在字节码层面上是相同的,因为所有while循环都可以转换成为for循环,例如上例中的while循环可以转换成如下的for循环,他们的字节码也是之前那个。
public void forLoop() { for(int i = 0; i < 2; i++) { //do nothing }}
do-while循环
示例:
public void doWhileLoop() { int i = 0; do { i++; } while (i < 2);}
被编译成:
0: iconst_0 1: istore_1 2: iinc 1, 1 5: iload_1 6: iconst_2 7: if_icmplt 210: return
- iconst_0:int型0放入操作栈
- istore_1:将0放入本地变量
- iinc:本地变量0加1
- iload_1:此处将本地变量载入操作栈(由于是i++,所以返回原来的值,还是0)
- iconst_2:将2载入栈顶
- if_icmplt:进行比较,如果大于0 ,转到第二步继续循环
文献
从Java代码到字节码
- JVM分析
- JVM基础:JVM参数设置、分析
- JVM基础:JVM参数设置、分析
- JVM系列:JVM参数设置、分析
- JVM系列:JVM参数设置、分析
- JVM内存监控、分析
- JVM内存结构分析
- JVM逃逸分析
- JVM分析工具介绍
- JVM 内存分析
- JVM运行情况分析
- JVM分析命令全
- JVM参数设置、分析
- JVM参数设置、分析
- JVM内存溢出分析
- JVM启动参数设置、分析
- jvm crash 分析
- jvm 内存分析工具
- 运维之python篇------2.斐波那契数列、模拟cp操作、生成8位随机密码
- 自动化安装
- 小Tips
- [2007CQOI]余数求和——除法分块
- Java基础之Dalvik和JVM的认识
- JVM分析
- 京东成武林魔头?几十家店铺因被侵害经营集体退出京东
- 第三章 虚拟机性能监控与故障处理工具
- android fat-aar.gradle中文注释
- Visual Studio 2017的离线安装包下载和安装
- 使用selenium中的driver.close()函数
- android中异常oom和memory leak
- vue项目-搭建(1)
- 2017 ccpc 秦皇岛 M(几何)