面试必问之JVM

一、jvm运行时的数据区域
面试必问之JVM文章插图
jvm运行时数据区域
在jvm运行时的数据区域 , 方法区和堆是线程共享的区域 , 而java 栈 , 本地方法栈 , 程序计数器 这三部分是每个线程私有的空间 。
1.程序计数器
程序计数器是很小的一块内存区域 , 可以看成是所执行的字节码文件的行号指示器 , 字节码解释器就是通过程序计数器的值选取下一条需要执行的指令 。 处理器切换线程时不会记录上个线程执行到了那个位置 , 为了每个线程能够切换到上次执行的位置 , 因此程序计数器是每个线程私有的 。 在执行Native方法时 , 由于Native方式不是由java语言编写的 , 不需要存储字节码行号 , 因此此时程序计数器为空 。
2.java虚拟机栈
java 虚拟机栈是线程锁私有的 , 生命周期和线程相同 , 随着线程的开始而产生 , 随着线程的消亡而结束 。 java虚拟机栈是描述java方法执行的内存模型 , 每个方法执行的同时就会创建一个栈帧 , 存储局部变量表 , 操作数栈 , 方法出口等信息 ,
3.本地方法栈
本地方法栈是为程序运行过程中使用到的本地方法而服务的 , 在虚拟机规范中 , 并没有对本地方法所使用的的语言 , 使用方法 , 数据结构进行规范 , 因此有的虚拟机会把虚拟机栈和本地方法栈合一 。
4.java 堆
【面试必问之JVM】 堆是内存区域最大的一块 , 是所有线程所共享的区域 , 在虚拟机启动的时候创建 , 主要用来存放实例对象 , 几乎所有的对象实例都是在堆中分配内存 , 堆也是垃圾收集器主要工作的地方 , java堆可以处在不连续的物理空间上 , 只要逻辑上连续即可 。
5.方法区
方法区也是被线程所共享的区域 , 存储的是已被虚拟机加载的类的信息 , 静态变量等 。 方法区可以不选择实现垃圾收集 , 这个区域主要是对常量的回收和类型的卸载 。
二、对象的创建 在java程序运行时 , 对象时时刻刻在被创建出来 , 当虚拟机遇到一个new指令时 , 先去检查这个类是否已经被加载 , 解析 , 初始化过 。 当检查完后 , 会为这个对象分配内存 , 内存分配完成后 , 需要将分配的空间都初始化为零值 , 当执行完init方法后 , 一个真正可用的对象才算被创建出来 。
三、对象的访问定位
目前主流的对象的访问方式有2种 , 使用句柄和直接指针访问 。
1.使用句柄访问 。
使用句柄访问的话 , java堆会划分出来一块内存为句柄池 , reference中存储的就是对象的句柄地址 , 句柄中包含了对象实例数据和类型数据各自的具体地址信息 。
面试必问之JVM文章插图
句柄访问
2.使用直接地址访问
如果使用直接地址访问 , 那么java堆对象的布局中就要考虑如何放置类型数据的相关信息 。 而reference中存储的就是对象地址 。
面试必问之JVM文章插图
直接指针访问对象
使用句柄访问最大的好处就是reference中储存的是稳定的句柄地址 , 在对象被移动的时候 , 只会改变句柄中的实例数据指针 。
使用直接指针的好处就是速度非常的快 , 节省了一次指针定位的时间 。