栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

JVM基础知识(更新中)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

JVM基础知识(更新中)

声明:本文是根据博主学习内容整理的自用笔记,仅作学习交流使用,如想观看视频的请移步享学java架构师VIP三期

JVM基础知识
    • JVM从编译到执行
      • 1. java程序的执行过程
      • 2. JVM,JRE,JDK的关系!
      • 3. JVM的跨平台与语言无关性
      • 4. JVM的发展(非重点)
        • 4.1 常见的JVM实现
      • JVM整体知识模块
      • 6. JVM的内存区域
        • 6.1 运行时数据区域
        • 6.2 JAVA方法的运行与虚拟机栈
        • 6.3 虚拟机栈

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

JVM从编译到执行 1. java程序的执行过程

一个 Java 程序,首先经过 javac 编译成 .class 文件,然后 JVM 将其加载到方法区,执行引擎将会执行这些字节码。执行时,会翻译成操作系统相
关的函数。JVM 作为 .class 文件的翻译存在,输入字节码,调用操作系统函数。
过程如下:Java 文件->编译器>字节码->JVM->机器码。

2. JVM,JRE,JDK的关系!

简单介绍一下
JVM 只是一个翻译,把 Class 翻译成机器识别的代码,但是需要注意,JVM 不会自己生成代码,需要大家编写代码,同时需要很多依赖类库,这个时
候就需要用到 JRE。
JRE 是什么,它除了包含 JVM 之外,提供了很多的类库(就是我们说的 jar 包,它可以提供一些即插即用的功能,比如读取或者操作文件,连接网络,
使用 I/O 等等之类的)这些东西就是 JRE 提供的基础类库。JVM 标准加上实现的一大堆基础类库,就组成了 Java 的运行时环境,也就是我们常说的 JRE
(Java Runtime Environment)。
但对于程序员来说,JRE 还不够。我写完要编译代码,还需要调试代码,还需要打包代码、有时候还需要反编译代码。所以我们会使用 JDK,因为 JDK
还提供了一些非常好用的小工具,比如 javac(编译代码)、java、jar (打包代码)、javap(反编译<反汇编>)等。这个就是 JDK。
具体可以文档可以通过官网去下载:https://www.oracle.com/java/technologies/javase-jdk8-doc-downloads.html
JVM 的作用是:从软件层面屏蔽不同操作系统在底层硬件和指令的不同。这个就是我们在宏观方面对 JVM 的一个认识

JVM 是一个虚拟化的操作系统,类似于 Linux 或者 Windows 的操作系统,只是它架在操作系统上,接收字节码也就是 class,把字节码翻译成操作系统上的
机器码且进行执行。

3. JVM的跨平台与语言无关性

跨平台:我们写的一个类,在不同的操作系统上(Linux、Windows、MacOS 等平台)执行,效果是一样,这个就是 JVM 的跨平台性。
为了实现跨平台型,不同操作系统有对应的 JDK 的版本。
https://www.oracle.com/java/technologies/javase/javase-jdk8-downloads.htm
跨语言(语言无关性):JVM 只识别字节码,所以 JVM 其实跟语言是解耦的,也就是没有直接关联,JVM 运行不是翻译 Java 文件,而是识别 class 文
件,这个一般称之为字节码。还有像 Groovy 、Kotlin、Scala 等等语言,它们其实也是编译成字节码,所以它们也可以在 JVM 上面跑,这个就是 JVM 的跨
语言特征。Java 的跨语言性一定程度上奠定了非常强大的 java 语言生态圈。

4. JVM的发展(非重点) 4.1 常见的JVM实现

  • Hotspot:目前使用的最多的 Java 虚拟机。在命令行 java –version。它会输出你现在使用的虚拟机的名字、版本等信息、执行模式。
  • Jrocket:原来属于BEA 公司,曾号称世界上最快的JVM,后被 Oracle 公司收购,合并于 Hotspot
  • J9: IBM 有自己的 java 虚拟机实现,它的名字叫做 J9.主要是用在 IBM 产品(IBM WebSphere 和 IBM 的 AIX 平台上)
  • TaobaoVM: 只有一定体量、一定规模的厂商才会开发自己的虚拟机,比如淘宝有自己的 VM,它实际上是 Hotspot 的定制版,专门为淘宝准备的,阿里、天 猫都是用的这款虚拟机。
  • LiquidVM: 它是一个针对硬件的虚拟机,它下面是没有操作系统的(不是 Linux 也不是 windows),下面直接就是硬件,运行效率比较高。
  • zing: 它属于 zual 这家公司,非常牛,是一个商业产品,很贵!它的垃圾回收速度非常快(1 毫秒之内),是业界标杆。它的一个垃圾回收的算法后来被 Hotspot 吸收才有了现在的 ZGC
JVM整体知识模块


JVM 能涉及非常庞大的一块知识体系,比如内存结构、垃圾回收、类加载、性能调优、JVM 自身优化技术、执行引擎、类文件结构、监控工具等。
但是在所有的知识体系中,都或多或少跟内存结构有一定的关系:
比如垃圾回收回收的就是内存、类加载加载到的地方也是内存、性能优化也涉及到内存优化、执行引擎与内存密不可分、类文件结构与内存的设计有关
系,监控工具也会监控内存。所以内存结构处于 JVM 中核心位置。也是属于我们入门 JVM 学习的最好的选
同时 JVM 是一个虚拟化的操作系统,所以除了要虚拟指令之外,最重要的一个事情就是需要虚拟化内存,这个虚拟化内存就是我们马上要讲到的 JVM 的内存

6. JVM的内存区域 6.1 运行时数据区域


运行时数据区的定义:Java 虚拟机在执行 Java 程序的过程中会把它所管理的内存划分为若干个不同的数据区域
Java 引以为豪的就是它的自动内存管理机制。相比于 C++的手动内存管理、复杂难以理解的指针等,Java 程序写起来就方便的多。
所以要深入理解 JVM 必须理解内存虚拟化的概念。
在 JVM 中,JVM 内存主要分为堆、程序计数器、方法区、虚拟机栈和本地方法栈等。
同时按照与线程的关系也可以这么划分区域:
线程私有区域:一个线程拥有单独的一份内存区域。
线程共享区域:被所有线程共享,且只有一份。
这里还有一个直接内存,这个虽然不是运行时数据区的一部分,但是会被频繁使用。你可以理解成没有被虚拟机化的操作系统上的其他内存(比如操作
系统上有 8G 内存,被 JVM 虚拟化了 3G,那么还剩余 5G, JVM 是借助一些工具使用这 5G 内存的,这个内存部分称之为直接内存)

6.2 JAVA方法的运行与虚拟机栈

虚拟机栈是线程运行 java 方法所需的数据,指令、返回地址。其实在我们实际的代码中,一个线程是可以运行多个方法的。
比如:

public class MethodAndStack {
    public static void main(String[] args) {

    }
    public static void A(){
        B();
    }

    public static void B() {
        C();
    }
    public static void C() {
    }
}

这段代码很简单,就是起一个 main 方法,在 main 方法运行中调用 A 方法,A 方法中调用 B 方法,B 方法中运行 C 方法。
我们把代码跑起来,线程 1 来运行这段代码, 线程 1 跑起来,就会有一个对应 的虚拟机栈,同时在执行每个方法的时候都会打包成一个栈帧。

简单说明一下
1.main方法开始运行,打包一个栈帧送入到虚拟机栈
2.main方法调用A方法,A方法打包入栈
3.A方法调用B方法,B方法打包入栈
4.B方法调用C方法,C方法打包入
方法运行完之后开始出栈
1.C方法运行完了,C出栈
2.接着B方法运行完了B出栈
3.接着A方法运行完了,A方法出栈
4.最后main方法运行完了,main方法出栈
这个就是Java方法运行对虚拟机栈的一个影响.虚拟机栈就是用来存储线程运行方法中的数据的.而每一个方法对应一个栈帧

6.3 虚拟机栈

栈的数据结构:先进后出(FILO)的数据结构,
虚拟机栈的作用:在 JVM 运行过程中存储当前线程运行方法所需的数据,指令、返回地址。
虚拟机栈是基于线程的:哪怕你只有一个 main() 方法,也是以线程的方式运行的。在线程的生命周期中,参与计算的数据会频繁地入栈和出栈,栈的生
命周期是和线程一样的。
虚拟机栈的大小缺省为 1M,可用参数 –Xss 调整大小,例如-Xss256k。
参数官方文档(JDK1.8):https://docs.oracle.com/javase/8/docs/technotes/tools/unix/java.html

栈帧:在每个 Java 方法被调用的时候,都会创建一个栈帧,并入栈。一旦方法完成相应的调用,则出栈。
栈帧大体都包含四个区域:(局部变量表、操作数栈、动态连接、返回地址)

  1. 局部变量表:
    顾名思义就是局部变量的表,用于存放我们的局部变量的(方法中的变量)。首先它是一个 32 位的长度,主要存放我们的 Java 的八大基础数据类
    型,一般 32 位就可以存放下,如果是 64 位的就使用高低位占用两个也可以存放下,如果是局部的一些对象,比如我们的 Object 对象,我们只需
    要存放它的一个引用地址即可。
  2. 操作数据栈:
    存放 java 方法执行的操作数的,它就是一个栈,先进后出的栈结构,操作数栈,就是用来操作的,操作的的元素可以是任意的 java 数据类型,所以我们知道一个方法刚刚开始的时候,这个方法的操作数栈就是空的。
    操作数栈本质上是 JVM 执行引擎的一个工作区,也就是方法在执行,才会对操作数栈进行操作,如果代码不不执行,操作数栈其实就是空的。

为什么说操作数栈本质上是 JVM 执行引擎的一个工作区
如果要自己造一个操作系统,常用的模式就是
CPU + 缓存 + 主内存 这三样是必要的
在cpu进行计算的时候 它需要把数据从主内存中放到缓存里面再来参与cpu的计算.
JVM 是一个模拟板的 操作系统
JVM 对应的CPU就是执行引擎 主内存就对应 栈,堆 缓存就是操作数栈 对用关系如下
CPU + 缓存 + 主内存
JVM执行引擎 + 操作数栈 + 缓存

  1. 动态连接:
    Java 语言特性多态(后续章节细讲,需要结合 class 与执行引擎一起来讲)。
  2. 返回地址:
    正常返回(调用程序计数器中的地址作为返回)、异常的话(通过异常处理器表<非栈帧中的>来确定)
    同时,虚拟机栈这个内存也不是无限大,它有大小限制,默认情况下是 1M。
    如果我们不断的往虚拟机栈中入栈帧,但是就是不出栈的话,那么这个虚拟机栈就会爆掉
public class StackError {
    public static void main(String[] args) {
        A();
    }

    public static void A() {
        A();
    }
}

运行结果如下

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/349007.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号