文章内容输出来源:拉勾教育Java高薪训练营,做者:孙里java
前言
对于面试中涉及的一些问题,大可能是层次多,知识点杂,不方便记忆,常常是一听就会,一面就忘。 我想到了一个对本身颇有效的记忆方法:类比联想记忆法。面试
其实这个方法你们很熟悉,也很经常使用,只是须要找到比较贴切且适合本身的事物进行关联。 特此分享一下本身的经验。本文目的不在于知识的讲解,而在于知识的持久化。若有错误,欢迎指正。数组
不知道你们以前对jvm的内存结构能记住多少,认真看完之后尝试每天回忆下这个场景。 由于除了第一次创建记忆链接之外,还须要常常在脑中反复强化这个链接,才能达到深入记忆的效果。数据结构
先总体浏览下JVM内存结构:大致上分为三个层次,二十多个知识点。
第一层
概念
-
类加载器:做用是将java 文件通过编译后会获得 .class 文件加载到内存。jvm
-
本地库接口:用native修饰的,不能和abstract共同使用的,不显示方法体但倒是用非Java语言实现方法体的方法。spa
-
运行时数据区:java虚拟机在执行Java程序的过程当中会把它管理的内存分为若干个不一样的数据区域。操作系统
-
执行引擎:jvm核心组成部分之一,创建在处理器、硬件和操做系统层面之上。引擎在执行代码时会有解释执行和编译执行两种选择,输入字节码文件,解析字节码输出结果。线程
类比
回顾完基本概念后,咱们再关联上一个更加容易记忆的场景,左侧为类比事物,右侧为对应知识点。对象
想象一下一辆刚刚驶入加油站的汽车:blog
-
司机拿起加油枪(类加载器)
-
对准加油口(本地库接口)开始加油(开始类加载的过程,后边会再分析)
-
加油的目的是供给发动机可使用的燃料(执行引擎)
-
而后才可让车继续保持行驶状态(运行时数据区)
第二层:类加载器
概念
-
加载:指的是将类的class文件读入到内存,并为之建立一个java.lang.Class对象。
-
连接:当类被加载以后,系统为之生成一个对应的Class对象,接着将会进入连接阶段,链接阶段负责把类的二进制数据合并到JRE中。类链接又可分为以下3个阶段。
-
验证:用于检验被加载的类是否有正确的内部结构,并和其余类协调一致。
-
准备:负责为类的静态变量分配内存,并设置默认初始值。
-
解析:将类的二进制数据中的符号引用替换成直接引用。
-
-
初始化:为类的静态变量赋予正确的初始值。
-
使用:业务处理中被引用。
-
销毁:再也不使用时被垃圾回收。
类比
再来类比下汽油使用的整个过程:
-
加载:将汽油添加到油箱。
-
连接:让发动机的油路中充满汽油。
-
验证:检查汽油是否符合发动机要求。
-
准备:汽油和发动机已完成启动前的准备状态。
-
解析:汽油开始燃烧并产出动力,化学燃料转换成物理的作功。
-
-
初始化:发动机启动完毕。
-
使用:汽车行驶过程当中,发动机使用汽油持续运转。
-
销毁:汽油被消耗。
第二层:运行时数据区
概念
-
程序计数器:记录的是正在执行的虚拟机字节码指令的地址。
-
虚拟机栈:Java 方法执行的内存模型。
-
本地方法栈:区别于Java 虚拟机栈的是,Java 虚拟机栈为虚拟机执行 Java 方法(也就是字节码)服务,而本地方法栈则为虚拟机使用到的Native 方法服务。
-
堆:这块区域是 JVM 所管理的内存中最大的一块。线程共享,主要是存放对象实例和数组。
-
方法区:属于共享内存区域,存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。
类比
-
程序计数器:记录汽车行驶距离的里程表。
-
虚拟机栈:电动车电池。
-
本地方法栈:汽油车油箱。
-
堆:能够堆放大件货物的后备箱。
-
方法区:能够提供操做汽车的各类方法的驾驶区域。
第三层:虚拟机栈
概念
栈帧( Frame)是用来存储数据和部分过程结果的数据结构,同时也被用来处理动态连接 (Dynamic Linking)、 方法返回值和异常分派( Dispatch Exception)。栈帧随着方法调用而建立,随着方法结束而销毁——不管方法是正常完成仍是异常完成(抛出了在方法内未被捕获的异常)都算做方法结束。
-
局部变量表:一组变量值存储空间,用于存放方法参数和方法内部定义的局部变量。
-
操做数栈:一个后进先出栈,其最大深度在编译的时候已经肯定了。当一个方法刚刚开始执行的时候,这个方法的操做数占是空的,在方法的执行过程当中,会有各类字节码指令往操做数占中写入和提取内容,这就是出栈/入栈动做。
-
动态连接:每个栈帧都包含一个执行运行时常量池中该栈帧所属方法的引用。持有这个引用是为了支持方法调用过程当中的动态链接。
-
返回出口:方法正常退出,将会返回程序结束其的值给上层方法,通过调整以后以指向方法调用指令后面的一条指令,继续执行上层方法。
-
正常完成出口:方法正确执行,执行引擎遇到方法返回的指令,回到上层的方法调用者。
-
异常完成出口:方法执行过程当中发生异常,而且没有处理异常,这样是不会给上层调用者产生任何返回值。
-
类比
每个方法从调用直至执行完成的过程,就对应着一个栈帧在虚拟机栈中入栈到出栈的过程。对应着每一次快递派送:
-
局部变量表:每次派送的货物清单。
-
操做数栈:货车的货箱,只能栈式搬运货物。
-
动态连接:实时动态规划路径。
-
返回出口:到达终点之后就能够返回了。
总结
最后,咱们再回顾下整个思路,方便平时反复回忆。
-
货车进入加油站进行加油时需用加油枪(类加载器)对准了加油口(本地库接口)。加过油的车可让发动机(执行引擎)运转起来,并保持行驶状态(运行时数据区)。
-
加油过程当中,汽油从油枪进入了油箱(加载),并抵达了发动机(连接)。这个过程当中车载电脑检查了汽油(验证),并使汽油和发动机都进入启动前的准备状态(准备)。而后汽油开始燃烧,转化为动力势能(解析),发动机启动完成后(初始化)开始使用汽油(使用),当汽油燃烧后就被消耗了(销毁)。
-
因此驾驶员坐在能够操做汽车的驾驶室(方法区)操纵货箱(堆)载满货物的货车时,会观察记录移动距离的里程表和油箱指示灯(程序计数器),判断何时须要再次加油。而油电混合的汽车也会借助油箱(本地方法栈)的汽油燃烧给电池充电(虚拟机栈)。
-
货车的目的是将货箱(操做数栈)的货物(局部变量)运送到目的地(返回出口),途中会借助导航地图实时调整路线(动态连接)。