JVM面试题-篇一


1.JVM两个子系统和两个组件

两个子系统:

  • 类装载子系统:根据给定的全限定类名来装载class文件到运行时数据区的方法区中。
  • 执行引擎:执行classes中的指令

两个组件:

  • 运行时数据区:jvm内存
  • 本地接口:与本地方法库交互,是Java语言与其它编程语言交互的接口。

2.类的加载

将类的.class文件中的二进制数据流读入内存,将其放在运行时数据区的方法区内,然后再堆区创建一个java.lang.class对象,用来封装类在方法区的数据结构。

3.运行时数据区(详)

  • 程序计数器:当前线程所执行的字节码的行号指示器。字节码解析器的工作就是通过改变这个指示器的值,来选取下一条需要执行的字节码指令。分支、循环、跳转、异常处理、线程恢复等功能,都需要依赖这个指示器来完成。
  • Java虚拟机栈:用于存储局部变量表、操作数栈、动态链接、方法出口信息等;
  • 本地方法栈:与虚拟栈的作用是一样的,只不过虚拟机栈是服务Java方法的,本地方法栈是为虚拟机调用native方法服务的。
  • Java堆:java虚拟机中内存最大的一块,被所有线程共享,几乎所有的对象实例都在这里分配内存。
  • 方法区:用于存储已被虚拟机加载的类信息,常量,静态变量,及时编译后的代码等数据。

4.对象创建的主要流程

虚拟机遇到一条new指令时,先检查常量池是否已经加载相应的类,如果没有必须执行相应的类加载。类加载完成后,接下来分配内存。若Java堆中内存是绝对规整的,使用“指针碰撞”方式分配内存;若不是绝对规整的就从空闲列表中分配内存,叫做“空闲列表方式”。划分内存时还需要考虑并发问题,有俩种处理方式:cas同步处理,或者本地线程分配缓冲池。内存分配完成后,进行内存空间的初始化操作,做一些必要的对象设置(元信息、哈希码)等,最后执行init方法。

5.对象内存分配

  • 指针碰撞:如果Java堆的内存是规整的,即所有用过的内存放在一边,所有空闲的放在另一边。分配时将位于中间的指针指示器向空闲的内存移动一段与对象大小相等的距离,这样便完成内存的分配工作。
  • 空闲列表:如果Java堆的内存不是规整的,则需要由虚拟机维护一个列表来记录那些内存是可用的,这样在分配时可以从列表中查询到足够大的内存分配给对象,并在分配后更新列表记录。

综上:选择哪种分配方式是由Java堆是否规整来决定的,而Java堆是否规整是由所采用的垃圾回收器所决定的,而Java堆是否规整是由所采用的垃圾收集器是否带有压缩整理功能所决定的。

6.内存分配时的并发安全问题

对象的创建在虚拟中是一个非常频繁的行为,哪怕只是修改一个指针所指向的位置,在并发情况下也是不安全的。可能出现正在给对象A分配内存,指针还没来得及修改,对象B又获得了原来的指针来分配内存的情况。

解决方案:

  • 方案一:对分配内存空间的动作进行同步处理(采用CAS+失败重试来保障更新操作的原子性)
  • 方案二:把内存分配的动作按照线程划分在不同的空间中进行。即每个线程在Java堆中预先分配一小块内存,称为本地线程分配缓冲。哪个线程要创建对象,就在本地线程分配缓冲(TLAB)上分配。只有线程TLAB用完并分配新的TLAB时,才需要同步锁。(通过-XX:+UseTLAB参数来设定是否启用TLAB,默认启用)。

7.对象的访问定位

Java程序需要通过JVM栈上的引用访问堆中的具体对象。对象的访问方式取决于JVM虚拟机的实现。目前主流的访问方式有句柄访问和直接指针访问俩种方式。

  • 指针:指向对对象,代表一个对象在内存中的起始地址。
  • 句柄:可以理解为指向指针的指针。句柄不直接指向对象,而是指向对象的指针(句柄不发生变化,指向固定的内存地址),再通过对象的直接指针指向对象的真实内存地址。

8.句柄访问

Java堆中划分出一块内存来作为句柄池,引用中存储对象的句柄地址,而句柄中包含了对象的实例数据与对象数据各自的具体地址信息。

优势:引用中存储稳定的句柄地址,在对象被移动时(垃圾收集时,移动对象时非常普遍的行为)只会改变句柄中实例数据指针的值,而引用本身不需要修改。

9.直接指针访问

如果使用直接指针访问的方式,引用中存储的直接就是对象的地址,那么Java堆对象内部必须考虑如何设置访问类型数据的相关信息。

优势:速度更快,节省了一次指针定位的时间开销。由于对象访问在Java中也是非常频繁的行为,因此这类开销积少成多后也是非常可观的执行成本。HotSpot中采用直接指针访问的方式。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值