面试官 : 明天来聊聊 JVM 的内存构造吧?
候选者:嗯,好的
候选者:前几次面试的时候也提到了:class 文件会被类加载器装载至 JVM 中,并且 JVM 会负责程序「运行时」的「内存治理」
候选者:而 JVM 的内存构造,往往指的就是 JVM 定义的「运行时数据区域」
候选者:简略来说就分为了 5 大块:办法区、堆、程序计数器、虚拟机栈、本地办法栈
候选者:要值得注意的是:这是 JVM「标准」的分区概念,到具体的实现落地,不同的厂商实现可能是有所区别的。
面试官 : 嗯,顺便讲下你这图上每个区域的内容吧。
候选者:好的,那我就先从「程序计数器」开始讲起吧。
候选者:Java 是多线程的语言,咱们晓得假如线程数大于 CPU 数,就很有可能有「线程切换」景象,切换意味着「中断」和「复原」,那天然就须要有一块区域来保留「以后线程的执行信息」
候选者:所以,程序计数器就是用于记录各个线程执行的字节码的地址(分支、循环、跳转、异样、线程复原等都依赖于计数器)
面试官:好的,了解了。
候选者:那接下来我就说下「虚拟机栈」吧
候选者:每个线程在创立的时候都会创立一个「虚拟机栈」,每次办法调用都会创立一个「栈帧」。每个「栈帧」会蕴含几块内容:局部变量表、操作数栈、动静连贯和返回地址
候选者:理解了「虚拟机栈」的组成后,也不难猜出它的作用了:它保留办法了局部变量、局部变量的计算并参加了办法的调用和返回。
面试官:ok,理解了
候选者:上面就说下「本地办法栈」吧
候选者:本地办法栈跟虚拟机栈的性能相似,虚拟机栈用于治理 Java 函数的调用,而本地办法栈则用于治理本地办法的调用。这里的「本地办法」指的是「非 Java 办法」,个别本地办法是应用 C 语言实现的。
面试官:嗯…
候选者:嗯,说完了「本地办法栈」、「虚拟机栈」和「程序计数器」,哦,上面还有「办法区」和「堆」
候选者:那我先说「办法区」吧
候选者:后面提到了运行时数据区这个「分区」是 JVM 的「标准」,具体的落地实现,不同的虚拟机厂商可能是不一样的
候选者:所以「办法区」也只是 JVM 中标准的一部分而已。
候选者:在 HotSpot 虚拟机,就会经常提到「永恒代」这个词。HotSpot 虚拟机在「JDK8 前」用「永恒代」实现了「办法区」,而很多其余厂商的虚拟机其实是没有「永恒代」的概念的。
候选者:咱们上面的内容就都用 HotSpot 虚拟机来阐明好了。
候选者:在 JDK8 中,曾经用「元空间」来代替了「永恒代」作为「办法区」的实现了
面试官:嗯…
候选者:办法区次要是用来寄存已被虚拟机加载的「类相干信息」:包含类信息、常量池
候选者:类信息又包含了类的版本、字段、办法、接口和父类等信息。
候选者:常量池又能够分「动态常量池」和「运行时常量池」
候选者:动态常量池次要存储的是「字面量」以及「符号援用」等信息,动态常量池也包含了咱们说的「字符串常量池」。
候选者:「运行时常量池」存储的是「类加载」时生成的「间接援用」等信息。
面试官:嗯…
候选者:又值得注意的是:从「逻辑分区」的角度而言「常量池」是属于「办法区」的
候选者:但自从在「JDK7」当前,就曾经把「运行时常量池」和「动态常量池」转移到了「堆」内存中进行存储(对于「物理分区」来说「运行时常量池」和「动态常量池』就属于堆)
面试官:嗯,这信息量有点多
面试官 : 我想问下,你说从「JDK8」曾经把「办法区」的实现从「永恒代」变成「元空间」,有什么区别?
候选者:最次要的区别就是:「元空间」存储不在虚拟机中,而是应用本地内存,JVM 不会再呈现办法区的内存溢出,以往「永恒代」常常因为内存不够用导致跑出 OOM 异样。
候选者:按 JDK8 版本,总结起来其实就相当于:「类信息」是存储在「元空间」的(也有人把「类信息」这块叫做「类信息常量池」,次要是叫法不同,意思到位就好)
候选者:而「常量池」用 JDK7 开始,从「物理存储」角度上就在「堆中」,这是没有变动的。
面试官:嗯,我听懂了
面试官 : 最初来讲讲「堆」这块区域吧
候选者:嗯,「堆」是线程共享的区域,简直类的实例和数组调配的内存都来自于它
候选者:「堆」被划分为「新生代」和「老年代」,「新生代」又被进一步划分为 Eden 和 Survivor 区,最初 Survivor 由 From Survivor 和 To Survivor 组成
候选者:不多 BB,我也画图吧
候选者:将「堆内存」离开了几块区域,次要跟「内存回收」无关(垃圾回收机制)
面试官:那垃圾回收这块等下次吧,这个延长上来又很多货色了
面试官 : 你要不先讲讲 JVM 内存构造和 Java 内存模型有啥区别吧?
候选者:他们俩没有啥间接关联,其实两次面试过后,应该你就有感觉了
候选者 :Java 内存模型是跟「并发」相干的,它是为了屏蔽底层细节而提出的标准,心愿在下层(Java 层面上) 在操作内存时在不同的平台上也有雷同的成果
候选者:Java 内存构造(又称为运行时数据区域),它形容着当咱们的 class 文件加载至虚拟机后,各个分区的「逻辑构造」是如何的,每个分区承当着什么作用。
面试官:理解了
今日总结:JVM 内存构造组成(JVM 内存构造又称为「运行时数据区域」。次要有五局部组成:虚拟机栈、本地办法栈、程序计数器、办法区和堆。其中办法区和堆是线程共享的。虚拟机栈、本地办法栈以及程序计数器是线程隔离的)
欢送关注我的微信公众号【Java3y】来聊聊 Java 面试,对线面试官系列继续更新中!
【对线面试官 - 挪动端】系列 一周两篇继续更新中!
【对线面试官 - 电脑端】系列 一周两篇继续更新中!
原创不易!!求三连!!