java虚拟机之内存区域和对象的访问定位

版权声明:转载请注明出处!! https://blog.csdn.net/IPI715718/article/details/84425494

运行时数据区域

虚拟机在执行java程序时,会将自己管理的内存区域划分为几个区域:程序计数器,虚拟机栈,方法区,Java堆,本地方法栈。

程序计数器,是内存中一块很小的区域,主要的工作是存储下一条指令的地址。这个区域的周期是线程级别的,每个线程都拥有一个程序计数器,执行的是java方法,里面存储的是一条字节码指令地址,如果运行的是Native方法(native方法是指由非java语言实现的方法),计数器为空。

java虚拟机栈,此内存区域也是线程私有的,主要用来描述java方法执行的内存模型,每个方法在执行过程中都会产生一个栈帧,栈帧由局部变量表,操作数栈,动态连接方法出口等信息,每个方法的执行和结束都伴随着栈帧的进栈和出栈。局部变量表中主要用来存放,基本数据类型的数据(int short long byte boolean char double float),和对象的引用(referrence类型,代表的可能是一个指向对象的指针变量,也可能是一个指向句柄的指针变量),内存空间在编译时就完成了内存空间的分配。可能产生的异常:当线程请求的深度超出了虚拟机所允许的深度会抛出StackOverflowerror异常,当存储数据时无法申请到足够的内存空间会抛出outofmemoryerror异常。

本地方法栈

本地方法栈和java虚拟机栈的发挥的作用相似,只是它是用来描述native方法的内存模型。

java堆

java堆是虚拟机中最大的内存区域,是线程共享的,主要就是用来存放对象实例和数组对象,也是GC主要管理的区域,也可以成为GC堆,GC收集器采用分代算法,内存区域可以分为新生代和老年代。在内存空间上是物理上不连续的内存空间,只是逻辑上的连续。在实例对象分配空间时,无法申请到更多的内存时会抛出outofmemoryerror异常。

方法区

方法区是一块线程共享的区域,用于存储加载的类信息,类静态变量,常量,编译后的代码等数据。方法区内存空间物理上是不连续的,还可以实现不垃圾回收。

运行时常量池

运行时常量池是方法区的一部分,Class文件除了由接口,方法,属性,版本外,还有编译时产生的常量和符号引用,这部分就存放在class文件的常量池中,在类加载是就会将class文件常量池中的内容存放在运行时常量池中。

对象的访问定位

访问的方式:句柄方式和直接指针

句柄方式:引用变量存储的是句柄地址,句柄中存储的是对象实例的地址和对象类型的地址。类似于寻址方式中的间接寻址。

优点:当实例对象的地址改变时只需改动句柄存储的地址即可,无需改动引用,。

缺点:二次访问,速度慢。

直接寻址:引用变量存储的直接就是java堆中实例对象的地址,对象类型指针再指向对象类型数据。

优点:直接访问,速度快。

 

猜你喜欢

转载自blog.csdn.net/IPI715718/article/details/84425494