JVM(一)虚拟机基础

JVM 全称Java Virtual Machine,也就是我们耳熟能详的Java 虚拟机。它能识别.class 后缀的文件,并且能够解析它的指令,最终调用操作系统上的函数,完成我们想要的操作。

Java执行流程

​ 当我们编写完程序之后文件就是.Java文件通过Javac指令编译之后就是.class文件,之后就是由JVM将类加载到方法区中,执行引擎执行这些字节码。

​ 过程如下:Java 文件->编译器>字节码->JVM->机器码

JVM的跨平台、跨语言性

  • 跨语言

    ​ 因为JVM是通过识别字节码(.class文件)的方式进行运行的,所以只要其他语言如果也可以编译为字节码文件则也可以在JVM上运行,例如:Groovy、Kotlin等等一些语言。所以JVM也是一定程度上奠定了Java强大的生态圈。

JVM相关实现

​ JVM规范的存在提供了一些JVM的具体的实现。

  • Hotspot

    使用最多的Java虚拟机,通过javac -version的命令可以看到。

  • Jrocket

    原隶属于BEA公司,号称最快的JVM,后被Oracle所收购,与Hotspot所合并。

  • J9

    IBM公司的JVM,主要用于自家产品上(IBM WebSphere 和IBM 的AIX 平台)。

  • TaobaoVM

    淘宝根据HotSpot为自身定制的JVM,目前阿里、天猫都在使用。

  • zing

    属于zual公司,很牛,但是很贵。它的垃圾回收速度非常快,之后它的垃圾回收算法被HotSpot所吸收形成了现在的ZGC。

JVM 整体知识模块

​ 从下图中可以看到JVM的知识模块是比较多的,但是基本上都会与内存结构牵扯到一些关系,所以内存结构是非常重要的一块知识点。

JVM 内存区

​ class文件初始化时会将初始化的数据存放到方法区和堆中,当调用方法的时候会生成一个线程,线程中会虚拟出一块内存,通过执行引擎执行指令集,操作数据进行入栈出栈以及程序计数器计数,最后返回地址,从而完成一个方法的调用。

  • 运行时数据区

    • 线程共享区
      • 方法区(规范,逻辑划分)

        方法区是JVM中的一种规范。JDK 1.7 是以永久代实现方法区,JDK 1.8是以元空间实现方法区的,所以存在不同的叫法。此区域是在class加载的时候就已经将数据加载到方法区中了。

        运行时常量池:主要存放引用地址。即在类加载的时候会存在将符号替换为直接引用的一部,其实就是将对象 a = new 对象()转换为对象 a = 地址,其地址就是存放在运行时常量池的。

      • 用于存放对象的。

    • 线程私有区
      • 线程

        此处每一个线程之间都是独立的、互不干扰的。每一个线程中都会存在三个大块—虚拟机栈、本地方法栈、程序计数器。

        虚拟机栈:主要核心为一个个栈帧,遵循栈的数据结构,先进后出。通过-Xss可以设置每个虚拟机栈的大小,一般默认为1MB(不同的操作系统默认设置的大小不一样)。每一个方法都会创建一个栈帧,直至方法执行结束则会出栈。

        局部变量:主要存放八大基本数据类型以及对象的引用。

        操作数栈:执行引擎的一个工作区,通过执行引擎执行指令集对数据进行入栈、出栈、计算等等。

        动态连接:后期文章。

        方法返回:将最终结果返回。

        本地方法:存放native所修饰的方法,因为这些方法都是由C/C++所实现的,可以通过此方法来操作系统。

        程序计数器:单独划分的一块内存,主要存放当前执行引擎所执行的地址。因为多线程的情况所以需要记录当前线程所执行的地址/行号,类似于CPU时间片轮转,它的内部也存在一个类似程序计数器。

        ​ 此区域是永远不会出现栈溢出异常。

  • 直接内存

    虚拟机内存以外的的内存,NIO可以操作此区域的内存。

    UnSafe类也可以,Ehcache就是基于此类实现的,但不建议自己使用。

posted @ 2021-01-24 17:58  某人人莫  阅读(218)  评论(0编辑  收藏  举报