Loading... # java运行时数据区与常用指令 ![jvm run time dara area.jpg][1] ## Runtime Data Area ### Program Counter PC(程序计数器),记录下一条指令的地址,虚拟机通过PC获取下一条指令运行,并改变PC的值。PC是线程独有的,Cpu会切换线程执行任务,为了保证准确记录各个线程的字节码执行位置,会给每个线程分配一个独有的PC。 ### JVM Stack 虚拟机栈,里面存放一个一个的栈帧(frame),每个方法对应一个栈帧,虚拟机栈也是线程独享的。 每个栈帧中包括: - Local Variable Table (局部变量表) - 记录方法中局部变量的下标值 - Operand Stack (操作数栈) - 每个栈帧都有一个自己的栈,该栈负责压入、弹出虚拟机指令,并完成逻辑运算。 - Dynamic Linking (动态链接) - 指令码第一次运行时,会指向一个符号地址,例如:Ljava.lang.String,在常量池中,它只是一个字符串符号,而Dynamic Linking就是将符号引用转换成直接引用,如果被引用的类没被加载,必要时,就加载它,下次再遇到相同的引用时,使用直接引用,省去解析步骤 - return address (返回地址) - 方法a调用了方法b,执行到b时,会跳到方法b的栈帧中执行,方法b返回时,方法a要继续原来的位置执行,return address就是记录b方法返回值的位置 ### Heap (堆) java对象存放位置,逻辑上分为新生代与老年代,通过GC来管理,是线程共享的。 ### Method Area 方法区,是一种概念上的存在,是线程共享的,具体细节由虚拟机开发者实现 - 在jdk1.8以前,叫做PermGen space,FGC不会清理该区域,大小在启动时指定,不能改变,字符串常量池位于该区域 - 从jdk1.8开始,叫做Meta Space,会触发FGC清理,默认大小无限制(物理内存大小),字符串常量池转移到了堆中 ### Runtime Constant Pool (运行时常量池) 方法区的一部分,主要存放Class的各种元数据信息与引用 ### Native Method Stack (本地方法栈) 执行由C或C++实现的native方法,与JVM Stack类似,为线程独享。 ### Direct Memory (直接内存) jvm可以直接访问的操作系统内核空间的内存,可以实现不将内核空间数据拷贝到线程工作内存中执行,避免了用户态到内核态之间的转换,提升了效率。典型例子就是java nio的实现。 ## 常用指令 ``` store :从栈顶取出一个对象,比如astore_1,a代表的是引用类型(同理,istore表示int,lstore表示long等等),1表示局部变量表的第一个变量,从栈顶取出一个引用型对象,赋值给第1号变量 load :将对象的引用装载到栈中,aload_0,将第0号变量对应的引用压入栈顶。 pop :从栈顶弹出一个对象 mul :imul取出栈顶的两个int类型数相乘,算出结果放在栈顶。 sub :isub取出栈顶两个int类型数做减法,结果放在栈顶。 invoke: 1. InvokeStatic :执行静态方法 2. InvokeVirtual :普通方法,多数方法执行都是InvokeVirtual 3. InvokeInterface :通过接口调用方法,比如List<String> list = new ArrayList<>(); list.add("a");因为list变量的类型List是个接口,所以该处是InvokeInterface。 4. InovkeSpecial :可以直接定位,不需要多态的方法,已知的只有private方法和构造方法,final方法不是InovkeSpecial 5. InvokeDynamic :lamba表达式或其他动态语言,动态产生的class,会用到的指令 ``` [1]: https://www.princelei.club/usr/uploads/2020/04/2210757911.jpg Last modification:June 11th, 2020 at 06:06 pm © 允许规范转载