深刻理解java虚拟机-运行时栈帧结构

栈帧是什么?java

用于支持虚拟机进行方法调用和方法执行的数据结构.数据结构

栈帧都存储了些什么东东?优化

每个栈帧都包括方法的局部变量表,操做栈,动态链接和方法返回地址和一些附加信息等.spa

线程,栈帧,方法之间的关系?线程

一个线程包括多个栈帧,在活动的线程中,栈顶的栈帧为当前栈帧,与该栈帧相关联的方法为当前方法.对象

局部变量表是什么?索引

是一组变量值存储空间,用于存放方法参数和方法内部定义的局部变量.内存

局部变量表空间是如何分配的?作用域

局部变量表容量以Slot为最小单位,一个Slot能够存放一个32位之内的数据类型.在Java程序编译为Class文件时,在方法的Code属性的max_locals数据项中肯定了该方法所须要分配局部变量表的最大容量.虚拟机

Slot存储的8种数据类型都是哪些?

 boolean,byte,char,short,int,float,reference,returnAddress.

reference类型表示什么?虚拟机能够经过reference类型作什么?

reference表示对一个对象实例的引用.能够经过reference类型作到两点

  1. 从引用中直接或间接的查找到对象在java堆中的数据存放的起始地址索引.

  2. 从引用中直接或间接的查找到对象在方法区中存储的类型信息.

一个Slot能够存放一个32位之内的数据类型,那对于64位的数据类型该如何处理?

虚拟机会以高位对齐的方式为其分配两个连续的Slot空间.

局部变量表中的Slot是否可重用?重用有哪些优缺点?

Slot是能够重用的,若是当前字节码PC计数器值超出某变量的做用域,那这个变量对应的slot就能够交给其余变量使用.

优势是能够节省必定的栈帧空间.

缺点是在某些状况下Slot复用会影响到GC的行为.如

第一次执行

void x(){

    byte[] b=new byte[65535]; 

    System.gc();

}

 此时由于变量b还在做用域以内,因此GC并未回收b占有的内存.

第二次执行

void x(){

    byte[] b=new byte[65535]; 

}

System.gc();

 此时的占有的内存仍然没有被回收.由于在第一次修改时,代码虽然已经离开了b的做用域,但此后并无任何对局部变量表的读写操做,b所占有的Slot尚未被其余变量所复用,因此GC Roots一部分的局部变量仍然保持的对它的关联.

第三次执行

void x(){

    byte[] b=new byte[65535]; 

    b=null;

}

System.gc();

 此时GC正常回收b占有的内存.但通过JIT编译优化后,b=null的代码能够省略,GC能够正确回收掉内存.

 什么是操做栈?

后入先出结构,最大深度在编译的时候写入到Code属性的max_stacks数据项中.其中的每个元素能够是任意java数据类型.

32位占用的栈容量为1, 64位占用的为2.

操做栈的使用过程和用途?

在方法的执行过程当中,会有各类字节码指令往操做栈中写入和提取内容,也就是 出栈/入栈 操做.

一般用作算数运算和调用其余方法时用来进行参数传递.

相关文章
相关标签/搜索