高频面试题-请聊一下JVM的内存结构!

这是我参与更文挑战的第11天,活动详情查看: 更文挑战面试

凡是三年以上开发经验的人,都会在简历上写上这么一句话,了解/熟悉JVM(内存结构),对垃圾回收机制有必定的理解。算法

可是每每大部分人是一问三不知的,或者是没准备充分,又或者是根本就是瞎编,最起码背一下概念,说不许面试官也不会呢。编程

接下来的文章会围绕着JVM、JMM、垃圾回收算法、垃圾回收器、如何调优几个方面的知识来聊一下。markdown

万里长征走出第一步。数据结构

今天咱们就来看一下JVM的内存结构,虽然是概念性的知识;但凭借着理论知识,结合平常的开发工做,日积月累下来,对平时的编程影响甚广。post

我这里是以JDK8为例,描述一下JVM的内存结构,若是想要了解更多更全面的知识,其实买本书看会更有效果,《深刻理解Java虚拟机》。性能

画了一张图,先看一下!spa

1.png

总体来讲,能够分为线程私有、线程共享两种类型,下面来看一下吧!线程

线程私有

程序计数器(Program Counter Register)

线程执行的字节码行号指示器,经过改变计数器的值来选取下一条要执行的字节码指令,只为Java方法计数。code

由于每一个线程有本身独立的行号,因为程序计数器所占内存小之又小,因此每一个线程使用独立计数器来处理是说得通的,这样并不会形成什么压力,反而由于每一个线程都私有一个计数器而快不少。

这也就是程序技术器是线程私有的缘由。

虚拟机栈 (Stack)(特性:后进先出)

Java方法执行时的内存模型,包含着诸多个栈帧。

栈帧是方法运行期间中的基础数据结构,每一个栈帧中主要包含了局部变量、操做数栈、动态链接、返回地址等等。

虚拟机栈中存储了线程中执行方法的栈帧,只有当方法执行完毕后,栈帧才会被销毁。

这里还有一个比较重要,并且问的比较频繁的一个知识点:如何引发StackOverflowError、OutOfMemoryError异常,为何?

这个问题咱们在以后的文章中会加以讲解,你们也能够自行去研究一下。

本地方法栈

本地方法栈与虚拟机栈的功能相似,虚拟机栈是为Java方法提供服务,而本地方法栈是为Native方法服务。

线程共享

元空间(MetaSpace)

用于存储被加载的类信息、常量、静态变量等等数据。

在JDK1.8以前,这些数据存储于方法区,也就是咱们常说的永久代(PermGen)。

不一样于永久代占用Java虚拟机内存,元空间是直接使用本地内存存储。

更换成元空间的好处不少,好比:

  1. 字符串常量池存放在永久代中的时候,容易出现内存溢出、性能问题。

  2. 类信息的大小难以肯定,由于永久代使用的是Java虚拟机内存,因此指定永久代内存时会有必定的难度。

  3. 在《深刻理解Java虚拟机》一书中提到过,其余虚拟机(如:JRockit、IBM J9)等,都没有永久代。这也就说明了Java虚拟机(HotSpot)没法与其余的虚拟机进行集成搭配;当使用了元空间后,这个问题就迎刃而解了。

堆 (Heap)

Java堆是全部线程共享的一块内存区域,也是Java虚拟机中所管理的最大的一块内存。

其中存储着几乎全部的对象实例,同时咱们以后要说的垃圾回收机制,也是针对堆来讲的,由于堆是垃圾收集器管理的主要区域。

若是根据垃圾回收集器的角度来看,堆还能分为新生代(Eden、From Survivor、To Survivor)、老年代。

这个我会在以后垃圾回收的文章里面仔细说一下,你们也能够自行查阅书籍。

相关文章
相关标签/搜索