JVM面试(二)内存区域划分

内存区划分

Java虚拟机在执行Java程序的过程中会把它锁管理的内存划分为若干个不同的数据区域。 这些区域有各自不同的用途,以及创建和销毁的时间。 有的区域随着虚拟机的进程一直存在,有的区域依赖用户线程的启动和结束而建立和销毁。

根据《Java虚拟机规范》的规定,Java虚拟机所管理的内存,包含一下几个运行时的数据区域。如图:

一般我们面试的时候,都是笼统的说:堆、栈、以及方法区,JDK 8之后方法区变为"元空间"。

这个说法不错,下面我们详解一下。

程序计数器

程序计数器区域⼀块内存较小的区域,它⽤于存储线程的每个执行指令,每个线程都有自己的程序计数器,此区域不会有内存溢出的情况。

由于Java虚拟机的多线程是通过线程的轮流切换、分配处理器执行时间的方式来实现的,在任何一个确定的时刻,一个处理器都只执行一个线程。

那么为了每次切换线程后能恢复到正确的执行位置,每条线程都需要一个独立的程序计数器, 所以这个程序计数器区域,是一个线程私有的内存。

虚拟机栈与本地线程栈

在很多情况下,我们都是把这两个合在一起说的。

两方面的原因,一个是《Java虚拟机规范》对本地方法栈使用的语言、使用方式等没有任何规定。 二是有些虚拟机确实把这两个合二为一,比如Hot-Spot虚拟机。

如果按照我这里的浅显理解的话,他们之间的区别可以这么说。

虚拟机栈的生命周期与线程相同,主要就是存储线程执行相关的局部变量信息。

本地方法栈也是如此,但是所执行的内容可能是虚拟机本地方法Native。

所以我们在面试的时候,可以只说虚拟机栈,甚至直说本地方法栈都可以。(在我面试数十次的经历中,确实没有遇到,挑这两个问区别的)

回到虚拟机栈,在每个方法被执行的时候,Java虚拟机都会在这个线程栈中创建一个"栈帧",用于存储局部变量表,操作数栈,方法出口等等信息。每一个方法被调用,直到执行完毕,就对应着一个栈帧从入栈到出栈的过程。

因为我们线程调用方法是一层层递进的,所以这个栈帧也是一层层叠加。当调用深度超过虚拟机所允许的深度时,就会抛出StackOverflowError异常。

还有一个情况是,栈帧层层递进的时候,虚拟机栈也是在不断增大。

如果栈的内存不足,并且提前分配好不能扩展;或者是扩展的时候无法申请到足够的内存,就会发生OutOfMemoryError异常。

堆区

堆区是各个线程共享的区域。

这也是老生常谈的问题,主要存放JVM启动时创建的数组和对象实例,还有垃圾回收也主要在堆区发生,还有分代模型等等巴拉巴拉。

具体内容我们可以到分析垃圾回收的时候详细说下。

需要注意的是,堆区也是可以被固定大小的,当内存不足无法扩展时,也会抛出OutOfMemoryError异常。

方法区

与堆区一样,也是各个线程共享的区域。

主要存储那些常亮,静态变量,代码缓存等数据。虽然《Java虚拟机规范》中把方法区描述为一个堆区的逻辑部分,但是名字却为"Non-Heap" 非堆,这就是要与堆区做区分。

这里不得不提一下"永久代" 这个概念,以前很多时候都是把永久代与方法区混为一谈。

这是因为HotSpot虚拟机的设计团队把垃圾收集器的分代设计扩展到了方法区,把方法区称为永久代来管理垃圾回收机制。

但是后来又把永久代的概念放到了本地内存中,一直到JDK8 之后,完全放弃了永久代的概念,改为在本地内存新实现的"元空间"来代替

粗略来说,就是最早时候方法区=永久代,后来统一并入本地内存的"元空间"中。

运行时常量池

也是方法区的一部分,主要 存储Class文件中编译期生成的各种字面量与符号引用

字面量是源代码中的固定值的表示法,即通过字面我们就能知道其值的含义。字面量包括整数、浮点数和字符串字面量;

符号引用包括类符号引用、字段符号引用、方法符号引用和接口方法符号引用。符号引用就是⼀个字符串,只要我们在代码中引用了⼀个非字面量的东西,不管它是变量还是常量,它都只是由⼀个字符串定义的符号,这个字符串存在常量池里,类加载的时候第一次加载到这个符号时,就会将这个符号引用(字符串)解析成直接引用(指针)。

相关推荐
考试宝4 小时前
国家宠物美容师职业技能等级评价(高级)理论考试题
经验分享·笔记·职场和发展·学习方法·业界资讯·宠物
面试鸭5 小时前
离谱!买个人信息买到网安公司头上???
java·开发语言·职场和发展
无尽的大道6 小时前
Java反射原理及其性能优化
jvm·性能优化
测试19987 小时前
2024软件测试面试热点问题
自动化测试·软件测试·python·测试工具·面试·职场和发展·压力测试
马剑威(威哥爱编程)8 小时前
MongoDB面试专题33道解析
数据库·mongodb·面试
程序员勋勋10 小时前
【自动化测试】如何在jenkins中搭建allure
职场和发展·jenkins·测试覆盖率
独行soc10 小时前
#渗透测试#SRC漏洞挖掘#深入挖掘XSS漏洞02之测试流程
web安全·面试·渗透测试·xss·漏洞挖掘·1024程序员节
咕咕吖10 小时前
对称二叉树(力扣101)
算法·leetcode·职场和发展
理想不理想v10 小时前
‌Vue 3相比Vue 2的主要改进‌?
前端·javascript·vue.js·面试
sszmvb123411 小时前
测试开发 | 电商业务性能测试: Jmeter 参数化功能实现注册登录的数据驱动
jmeter·面试·职场和发展