JVM内存区域常见面试题
1.介绍下Java内存区域
程序计数器,Java虚拟机栈,本地方法栈是线程私有的,堆,方法区,直接内存是线程共享的。
程序计数器,Java虚拟机栈,本地方法栈是线程私有的,堆,方法区,直接内存是线程共享的。
程序计数器:为了线程切换后能恢复到正确的执行位置,是唯一一个不会出现OutOfMemoryError的内存区域,生命周期随着线程的创建而创建,随着线程的结束而死亡。
Java虚拟机栈:是Java方法执行的内存模型,每次方法调用的数据都是通过栈传递的。
本地方法栈:和虚拟机栈发挥作用相似,,虚拟机栈为执行Java方法服务,而本地方法栈则为虚拟机使用到的Native方法服务
方法区:用于存储已被虚拟机加载的数据
直接内存:避免了在Java堆和Native堆之间来回赋值数据
2.Java对象的创建过程(五步,建议默写出来并且要知道每一步虚拟机做了什么)
(1)类加载检查
虚拟机遇到一条 new 指令时,首先将去检查这个指令的参数是否能在常量池中定位到这个类的符号引用,并且检查这个符号引用代表的类是否已被加载过、解析和初始化过。如果没有,那必须先执行相应的类加载过程。
(2)分配内存
虚拟机将为新生对象分配内存,分配方式有 “指针碰撞” 和 “空闲列表” 两种,选择哪种分配方式由 Java 堆是否规整决定,而 Java 堆是否规整又由所采用的垃圾收集器是否带有压缩整理功能决定。
(3)初始化零值
内存分配完成后,虚拟机需要将分配到的内存空间都初始化为零值
(4)设置对象头
初始化零值完成之后,虚拟机要对对象进行必要的设置
(5)执行init方法
3.对象的访问定位的两种方式(句柄和直接指针两种方式)
句柄:java堆中将会划分出一块内存来作为句柄池,reference中存储的就是对象的句柄地址
直接指针:reference存储的直接就是对象的地址,速度快,节省了一次指针定位的时间开销