1

1.什么是JVM

2.JVM由哪几部分组成

3.程序计数器

4.虚拟机栈

5.本地方法栈

6.堆

7.方法区

1.什么是JVM
在我们日常的JAVA开发过程中,从原来一开始使用的的Servlet,JSP,再到后来出现的SSM,SpringBoot,以及队列,注册中心等等。这些都是所谓的JAVA上层技术,也是大家都在重点关注和学习的地方。但是大家对于JAVA的技术核心JAVA虚拟机了解甚少。
所以大部分人都认为这些上层技术才是重点,基础知识并不重要,其实这是一种"本末倒置的心态"。如果我们把API比喻成数学公式的话,那么JAVA虚拟机的知识就好比公式的推导过程。
所谓虚拟机(JVM)就是指运行JAVA字节码的虚拟计算机,就是能将JAVA的字节码文件翻译成操作系统能执行的文件,那么JAVA字节码文件又是哪来的呢?是由JAVAC编译器编译而来的(Javac是一种编译器,它的任务就是将Java源代码语言转化为JVM能够识别的一种语言),所以整个编译和执行过程如下:

image.png

image.png

2.JVM由哪几部分组成
image.png
我们先来看一张图:
JVM由类加载子系统,运行时数据区,以及执行引擎和本地方法接口组成,我们先来讲解一下它们的整体工作流程,再挨个部分进行分析:
我们写的JAVA代码,先由类装载子系统加载入运行时数据区中,这样,JAVA在运行的过程中,就可以从内存中获取类,变量,等信息了,同时,运行时数据区这也是我们等等主要要介绍的区域。
但是在字节码装载到JVM以后,字节码并不能运行在操作系统之上,所以这时候我们需要执行引擎,它将字节码指令解释/编译为对应平台上的本地机器指令。简单来说,JVM中的执行引擎充当了将高级语言翻译为机器语言的译者。

本地方法接口的作用是融合不同的编程语言为java所用,它的初衷是融合C/C++程序。

今天我们重点来讲解运行时数据区的组成以及每一个部分的作用。
image.png

3.程序计数器
每一个线程都有一个程序计数器,是线程私有的,它的作用就是用来存储代码当前运行的位置,也就是所谓的当前线程所执行的字节码的行号指示器。
用以完成循环,跳转,异常处理等基础功能,是在JAVA虚拟机规范中没有规定任何OutOfMemoryError情况的区域。

4.虚拟机栈
虚拟机栈处于线程独占区
栈主管JAVA程序的运行,是在线程创建的时候创建,它的生命周期是跟随线程的生命周期,线程结束栈内存就释放,对于栈来说,不存在任何垃圾回收问题,只要线程一结束改栈就Over,生命周期和线程一致,是线程私有的,8种基本类型变量+对象的引用变量+实例方法都是在函数的栈内存中分配。

接下来我们来讲解一下栈的运行原理:

首先,栈有两个操作,出栈和入栈。每当我们运行一个方法的时候,都会对栈进行入栈操作,方法执行完毕后,就会执行出栈操作。

我们用代码来举例:

 public static void main(String[] args) {
        System.out.println("main()");
        method01();
    }

    public static void method01(){
        System.out.println("method01()");
        method02();
    }

    public static void method02(){
        System.out.println("method02()");
    }

main方法执行后,main()方法会有一个入栈操作:
image.png
然后再运行method01和method02方法:
image.png
method01和method02就会执行连续入栈操作。
接着
method02执行完毕后,出栈
method01执行完毕后,出栈
main执行完毕后,出栈
每执行一个方法都会产生一个栈帧,保存到栈的顶部,顶部栈就是当前的方法,该方法执行完毕后自动将此栈帧出栈。
每个栈帧用于存储局部变量表,操作数栈,动态链接,方法出口等信息。

5.本地方法栈
本地方法栈处于线程独占区
本地方法栈和虚拟机栈所发挥的作用是非常相似的,它们之间的区别不过是虚拟机栈是非虚拟机执行Java方法(也就是字节码)服务,而本地方法栈则是为虚拟机执行Native方法服务的。
在虚拟机规范中对本地方法栈中方法使用的语言、使用方式与数据结构并没有强制规定,因此具体的虚拟机可以自由实现它。

6.堆
一个JVM实例只存在一个堆内存,是垃圾收集器的主要工作区域,堆内存的大小是可以调节的,类加载器读取了类文件后,需要把类,方法,常量放到堆内存中,保存所有引用类型的真实信息,以方便执行器执行
image.png

7.方法区
方法区处于线程共享区
存储运行时常量池,已被虚拟机加载的类信息,常量,静态变量,即时编译后的代码等数据
一般垃圾回收不选择回收这个区域
方法区中包含的都是在整个程序中永远唯一的元素,如class,static变量。


苏凌峰
73 声望38 粉丝

你的迷惑在于想得太多而书读的太少。