public class JVM {
public static void main(String[] args) {
int i = 8;
i = i++;
System.out.println(i);
}
}
请问最后答案是多少?
答案是8。
为什么呢?你看了这篇文章就了解个大概了。
运行时数据区是非常重要的一个执行区。
jvm 运行时的区域一共有这么几个区域
注意:非static方法的LocalVariableTable里会有this
ps:这个是上一篇说到的Jclasslib idea的插件(方便开发者读取并分析内存的帮手)
0 bipush 8
2 istore_1
3 iload_1
4 iinc 1 by 1
7 istore_1
8 getstatic #2 <java/lang/System.out : Ljava/io/PrintStream;>
11 iload_1
12 invokevirtual #3 <java/io/PrintStream.println : (I)V>
15 return
jvm会把class 方法解析成一个个字节码指令。每个指令对应的就是jvm的操作。
分析:
第一步是压栈 把8放在栈里面
第二步是 把int值放在局部变量表 也就是LocalVariableTable里 的1位置
这两步完成的时候也就int i = 8 这个指令完成
第三步是 把局部变量表 1这个位置拿出来 压栈 也就是把i又拿进来了
第四步是 把局部变量表 1这个位置加1 所以 这时候局部变量表的i已经变成9了 但是栈里面是8
第五步是 和第二部一样 又把栈里的8 放在了1位置 也就是i覆盖了9
第六步也就是返回 所以就是8
以上就是每个栈里面的东西
虚拟机的运行,类似于一个循环
while(not end){
取pc的位置,找到对应位置的指令
执行该指令
PC++
}
不归jvm管 归os管 省了拷贝过程比io 0拷贝
字符串常量位于PermSpace
FGC不回收 bug
大小启动的时候指定,不能变
会触发FGC清理
字符串常量位于堆
不设定的话,最大就是物理内存
方式区是逻辑上的概念 具体的实现是Perm Space 和Meta Space是具体的实现
思考 如何证明1.7 位于perm 而1.8位于heap?
结合GC 一直创建字符串常量,观察堆和metaspace
注意:这里就是sipush 200 和之前讲的bipush 8 有点不一样 所以大家一定要自己ctrl点进去自己看 sipush 是因为已经超过了127 一个字节的大小(-128到127),所以才会默认转成short类型,还有其他类似于ldc,ldc2_w 也是。ldc是从常量池里拿数据压栈,所以这里是想说可以多去看看指令集的解释,比直接模仿印象更深刻,懂得也就更多。
补充:
基于栈的指令集 是jvm的 指令集
基于寄存器的指令集是os的指令集
hotspot 的local variable table 类似于寄存器
store
load
pop
mul
sub
invoke
InvokeVirtual
因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- ryyc.cn 版权所有 湘ICP备2023022495号-3
违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务