JVM虚拟机面试题汇总
经历过很多面试和笔试,看过很多别人的面经,总结了JVM虚拟机的面试题,希望能给面试的童鞋一些帮助。不过,我这里就不想浪费笔墨描述问题的原理了,每个问题都附有答案,如果答案看不懂地方,可以自行百度或者看其他人的博客。 ### JVM虚拟机面试题知识点详解 #### 一、JVM运行时内存结构 JVM运行时数据区(Runtime Data Area)主要包括以下几部分: 1. **程序计数器(Program Counter Register)**:是一块较小的内存空间,当前线程所执行的字节码的行号指示器。每条线程都有一个独立的程序计数器,因此它是线程私有的。如果执行的是Java方法,计数器记录的是正在执行的虚拟机字节码指令地址;如果是Native方法,则该计数器值为空。 2. **Java虚拟机栈(Java Virtual Machine Stacks)**:描述的是Java方法执行的内存模型,每个方法被执行时都会创建一个栈帧用于存储局部变量表、操作数栈、动态链接、方法出口等信息。每调用一次方法,JVM栈就会增加一个栈帧,每退出一个方法,JVM栈就会弹出一个栈帧。栈帧结构如下: - **局部变量表(Local Variable Table)**:用于存放编译期可知的各种基本数据类型、对象引用等。 - **操作数栈(Operand Stack)**:主要用于保存计算过程中产生的中间结果,也用来存放操作数。 - **动态链接(Dynamic Link)**:包含一个指向运行时常量池中该栈帧所属方法的引用。 - **方法返回地址(Return Address)**:调用者上下文的信息,用来恢复之前的字节码指令地址。 3. **本地方法栈(Native Method Stacks)**:与Java虚拟机栈的作用非常相似,其区别在于Java虚拟机栈服务Java方法,而本地方法栈服务于Native方法。 4. **Java堆(Java Heap)**:所有线程共享的一块内存区域,在虚拟机启动时创建。此内存区域的唯一目的就是存放对象实例,几乎所有的对象实例都在这里分配内存。堆可以细分为: - **新生代(Young Generation)** - **Eden区**: 新生代中大部分对象首先分配在这个区域。 - ** Survivor 区**: 为了提高内存的利用率,将新生代划分为两个Survivor区,每次GC后,对象会从一个Survivor区复制到另一个Survivor区。 - **老年代(Old Generation)**: 存放多次经过GC仍然存活的对象。 5. **方法区(Method Area)**:用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。虽然方法区和Java堆一样,也会受到内存溢出的影响,但方法区的“内存溢出”异常表现并不是`OutOfMemoryError`,而是`PermGen space`的错误,这是由于HotSpot VM使用-XX:MaxPermSize来控制这块内存。 #### 二、JVM参数设置 1. **堆参数**: - `-Xmx`: 最大堆内存。例如:`-Xmx512m`。 - `-Xms`: 初始堆内存。例如:`-Xms256m`。 - `-XX:MaxNewSize`: 最大年轻代内存。 - `-XX:NewSize`: 初始年轻代内存。新生代一般为堆大小的1/3或1/4。 - `-XX:MaxPermSize`: 最大永久代内存。 - `-XX:PermSize`: 初始永久代内存。 - `-XX:+PrintGCDetails`: 打印GC详细信息。 - `-XX:NewRatio`: 新生代与老年代的比例。 - `-XX:SurvivorRatio`: 新生代中Eden与Survivor的比值。 2. **栈参数**: - `-Xss`: 设置每个线程的堆栈大小。JDK 1.5+每个线程堆栈大小为1M。 #### 三、对象创建和内存溢出 1. **对象创建**: - 检查指令的参数能否在常量池中找到类的符号引用,并确保这个类已经被加载、解析和初始化。 - 内存分配:根据对象大小,采用指针碰撞或空闲列表的方式分配内存。 - 对象初始化:包括对象的哈希码、GC分代年龄等设置。 - 对象头:包括对象自身信息和类型指针。 2. **对象的内存布局**: - **对象头(Object Header)**:存储对象自身的属性,如哈希码、GC分代年龄等。 - **实例数据(Instance Data)**:对象真正的数据。 - **对齐填充(Padding)**:确保对象大小为8字节的整数倍。 3. **对象访问定位**: - **句柄访问**: 通过句柄池中的句柄来访问对象实例数据。 - **直接指针**: 直接通过对象的地址访问对象实例数据。 4. **内存溢出(Out Of Memory Error, OOM)**: - **堆溢出**:对象实例数量超过最大堆容量限制。 - **虚拟机栈和本地方法栈溢出**:线程请求的栈深度大于虚拟机所允许的最大深度,或虚拟机在扩展栈时无法申请到足够的内存空间。 - **方法区溢出**:当方法区无法满足新的内存分配需求时,将抛出`OutOfMemoryError`异常。 以上是关于JVM虚拟机的一些核心概念和知识点的详细介绍,这些内容对于理解JVM的工作原理和优化性能至关重要。希望对你准备面试有所帮助。
剩余10页未读,继续阅读
- gnui8510162019-06-25可以 不错的资源
- 粉丝: 39
- 资源: 19
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助