JVM 面试

本文详细分析了JVM的内存结构,包括程序计数器、虚拟机栈、本地方法栈、堆和方法区的作用。同时,介绍了栈帧的组成以及JVM的相关参数设置。此外,还探讨了类加载器的双亲委派模型及其可能的打破方式。

Survive by day and develop by night.
talk for import biz , show your perfect code,full busy,skip hardness,make a better result,wait for change,challenge Survive.
happy for hardess to solve denpendies.

目录

在这里插入图片描述

概述

系统架构师之路

需求:

1.解决三高问题
2.技术选型问题

设计思路

3.常见的面试题汇总

实现思路分析

Q:JVM内存结构
A:主要有:程序计数器、Java虚拟机栈、本地方法栈、堆、方法区
一、程序计数器
作用:存储着下一条字节码指令的地址
该内存空间为线程私有的,因为在多线程执行时,为了让CPU能在线程切换后恢复到正确的执行位置,每个线程都需要有自己的程序计数器

二、Java虚拟机栈
作用:每个线程会有自己的私有栈,当线程调用一个方法,则该方法会被组装为栈帧压入栈中,方法执行完则出栈,栈顶栈帧为当前执行的方法。
三、本地方法栈
作用:与虚拟机栈作用相似,区别在于虚拟机栈用于为虚拟机执行Java方法服务,本地方法栈则为虚拟机执行Native方法服务

四、堆
作用:用于存放对象实例和数组。
是被所有线程共享的一块内存区域,因为需要内存回收的缘故,我们也将Java堆细分为新生代和老年代。内存回收可看内存回收策略

五、方法区
作用:存储被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据

Q:什么是栈帧?
栈帧由局部变量表、操作数栈、动态链接、方法返回地址组成
局部变量表
作用:存放方法参数和方法内部定义的局部变量。
局部变量表以容量槽Slot为最小单位,其中boolean、byte、char、short、int、float、reference或returnAddress为一个Slot,long和double为两个Slot。一般来说一个Slot占用32位长度的内存空间,其中reference类型表示对一个对象实例的引用,通过引用,能查找到对象在堆中数据存放的起始地址索引。returnAddress已经很少见了,已被异常表代替。

操作数栈
作用:用于存放方法执行过程中,字节码指令进行入栈和出栈操作时,写入和提取的内容。
boolean、byte、char、short、int、float所占的栈容量为1,long和double所占的栈容量为2。

动态链接
符号引用一部分会在类加载阶段或者第一次使用的时候就转化为直接引用,这种转化称为静态解析。
另外一部分将在每一次运行期间转化为直接引用,这部分成为动态连接。

方法返回地址
作用:方法退出之后,需要返回到方法被调用的位置,程序才能继续执行。

方法有两种退出方式

  1. 正常完成出口:执行引擎遇到任意一个方法返回的字节码指令,这时候可能会有返回值传递给上层的调用者,此种退出方式,栈帧中会保存调用者PC计数器的值。

  2. 异常完成出口:当方法执行过程遇到异常,且异常没有在方法体内得到处理,只要在方法的异常表中没有搜索到匹配的异常处理器,就会导致方法退出,此种退出方式,返回地址是要通过异常处理器表来确定,栈帧中不保存这部分信息
    Q:JVM有哪些参数?

一、栈参数设置
通过-Xss可以设置每个线程的栈大小,该数值该值过小则会容易引起StackOverFlowError,该值过大则会使线程占用内存增多。默认设置为1M。
二、堆参数设置
通过-Xmx设置堆最大内存,-Xms设置堆初始内存,该值过小容易引起OOM。一般设置为老年代存活对象的3-4倍。

Q:什么是双亲委派模型?

双亲委派模型将类加载器分为四层,除了顶层,其余类加载器都有自己的父类加载器。顶层类加载器由C++实现,其余由Java实现。
启动类加载器:顶层类加载器,负责将存放在<JAVA_HOME>\lib目录或被-Xbootclasspath参数所指定路径下,固定文件名(如rt.jar)的类库加载到虚拟机内存中。
扩展类加载器:第二层类加载器,负责将存放在<JAVA_HOME>\lib\ext目录或被java.ext.dirs系统变量所指定的路径下的类库加载到虚拟机内存中
应用程序类加载器:第三层类加载器,负责将存放在用户类路径(ClassPaht)目录下的类库加载到虚拟机内存中

自定义类加载器:第四层加载器,由用户编写的类加载器

双亲委派模型的工作过程:
如果一个类加载器收到了类加载的请求,它不会自己先去加载这个类,而是把请求委派给父类请求加载器完成,因此所有加载请求最终都会送到顶层的启动类加载器,只有当父加载器反馈自己无法完成这个加载请求时(搜索范围中没有找到所需的类),子加载器才会尝试自己去加载。

打破双亲委派模型:
打破双亲委派机制则不仅要继承ClassLoader类,还要重写loadClass和findClass方法。

参考资料和推荐阅读

  1. 暂无

欢迎阅读,各位老铁,如果对你有帮助,点个赞加个关注呗!~
如有侵权请联系删除之

### JVM面试常见问题及解答 #### 一、JVM内存区域划分 JVM的内存被划分为多个不同的区域,这些区域各自承担着特定的功能。具体来说,JVM会向操作系统申请一块连续的物理内存空间,并在此基础上进一步细分成若干逻辑部分[^3]。 - **方法区**:用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。 - **堆**:所有线程共享的一块区域,几乎所有的对象实例都在这里分配内存。这是垃圾收集器管理的主要区域。 - **栈**:每个线程创建时都会有一个独立的栈,保存局部变量表、操作数栈、动态链接、返回地址等信息。 - **本地方法栈**:与Java方法使用的栈相对应,服务于Native方法调用。 - **程序计数器**:记录当前线程执行字节码指令的位置;如果正在执行的是一个Java方法,则记录下一条要执行的指令地址;如果是native方法则为空。 #### 二、垃圾回收机制简介 在Java应用程序运行期间,随着新对象不断创建,可用内存逐渐减少。为了防止内存耗尽并提高性能,JVM提供了自动化的垃圾回收功能(GC)[^2]。其核心目的是识别不再使用的对象并将它们占用的空间重新收回给系统。这样做的好处在于简化了开发人员的工作流程——无需手动追踪每一个对象的生命期或担心因疏忽而导致资源泄漏等问题。 ##### 主要目标如下: - **清除无用对象**:通过周期性的扫描找出那些已经没有任何引用指向的对象,并将其标记为可清理状态; - **优化内存布局**:当某些区域内存在大量碎片化的小块未连贯空闲空间时,GC可以整理这些零散片段使之成为较大范围的整体空白区间以便后续高效利用; - **提升应用响应速度**:合理配置GC参数能够有效降低停顿时间从而改善用户体验。 ```java // 示例代码展示如何触发一次完整的Full GC过程 System.gc(); // 请求JVM尽快启动一次全局级别的垃圾收集动作 ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值