JVM的工作流程

目录

1.JVM 简介 

2.JVM 执行流程 

3. JVM 运行时数据区

   3.1 堆(线程共享)

3.3 本地方法栈(线程私有)

3.4 程序计数器(线程私有)

3.5 方法区(线程共享) 

4.JVM 类加载

① 类加载过程

1) 加载

2) 验证

3) 准备

4) 解析

5) 初始化

② 双亲委派模型

双亲委派模型的优点


1.JVM 简介 

        JVM Java Virtual Machine 的简称,意为 Java 虚拟机。 虚拟机是指通过软件模拟的具有完整硬件功能的、运行在一个完全隔离的环境中的完整计算机系统。
       常见的虚拟机: JVM VMwave Virtual Box

2.JVM 执行流程 

     程序在执行之前先要把java代码转换成字节码(class文件),JVM 首先需要把字节码通过一定的方式 类加载器(ClassLoader把文件加载到内存中 运行时数据区(Runtime Data Area,而字节码文件是 JVM 的一套指令集规范,并不能直接交个底层操作系统去执行,因此需要特定的命令解析器 行引擎(Execution Engine将字节码翻译成底层系统指令再交由CPU去执行,而这个过程中需要调用其他语言的接口 本地库接口(Native Interface来实现整个程序的功能,这就是这4个主要组成部 分的职责与功能。

                                 

3. JVM 运行时数据区

           JVM 运行时数据区域也叫内存布局,但需要注意的是它和 Java 内存模型( (Java Memory Model ,简称 JMM)完全不同,属于完全不同的两个概念,它由以下 5 大部分组成:

   3.1 堆(线程共享)

    堆的作用:程序中创建的所有对象(new)都在保存在堆中

     堆里面分为两个区域:新生代和老生代,新生代放新建的对象,当经过一定 GC 次数之后还存活的对象会放入老生代。新生代还有 3 个区域:一个 Endn + 两个 Survivor S0/S1 )。

 3.2 Java虚拟机栈(线程私有)

        Java 虚拟机栈的作用: Java 虚拟机栈的生命周期和线程相同, Java 虚拟机栈描述的是 Java 方法执行的内存模型:每个方法在执行的同时都会创建一个 栈帧 (Stack Frame )用于 存储局部变表、操作数栈、动态链接、方法出口等信息 。咱们常说的堆内存、栈内存中,栈内存指的就是虚拟栈。

 Java 虚拟机栈中包含了以下 4 部分:

3.3 本地方法栈(线程私有)

    本地方法栈和虚拟机栈类似,只不过 Java 虚拟机栈是给 JVM 使用的,而本地方法栈是给本地方法使用 的。

3.4 程序计数器(线程私有)

        程序计数器的作用:用来记录当前线程执行的行号的。
        程序计数器是一块比较小的内存空间,可以看做是当前线程所执行的字节码的行号指示器。
        如果当前线程正在执行的是一个Java 方法,这个计数器记录的是正在执行的虚拟机字节码指令的地址; 如果正在执行的是一个Native 方法,这个计数器值为空。
什么是线程私有?
           由于JVM的多线程是通过线程轮流切换并分配处理器执行时间的方式来实现,因此在任何一个确定的时 刻,一个处理器(多核处理器则指的是一个内核)都只会执行一条线程中的指令。因此为了切换线程后能 恢复到正确的执行位置,每条线程都需要独立的程序计数器,各条线程之间计数器互不影响,独立存 储。我们就把类似这类区域称之为"线程私有"的内存。

3.5 方法区(线程共享) 

        方法区的作用:用来存储被虚拟机加载的类信息、常量、静态变量(static)、即时编译器编译后的代码等数据 的。

         在 HotSpot 虚拟机的实现中,在 JDK 7 时此区域 叫做永久代(PermGen),JDK 8 中叫做元空间(Metaspace)。

      运行时常量池

运行时常量池是方法区的一部分,存放字面量与符号引用。
字面量 : 字符串 (JDK 8 移动到堆中 ) final 常量、基本数据类型的值。
符号引用 : 类和结构的完全限定名、字段的名称和描述符、方法的名称和描述符。

4.JVM 类加载

① 类加载过程

 对于一个类来说,它的生命周期是这样的:

1) 加载

        “加载 Loading )阶段是整个 类加载 Class Loading )过程中的一个阶段,它和类加载 Class Loading 是不同的,一个是加载 Loading 另一个是类加载 Class Loading ,所以不要把二者搞混了。
在加载 Loading 阶段, Java 虚拟机需要完成以下 三件事情
1 )通过一个类的全限定名来获取定义此类的二进制字节流。
2 )将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构。
3 )在内存中生成一个代表这个类的 java.lang.Class 对象,作为方法区这个类的各种数据的访问入口。

2) 验证

        验证是连接阶段的第一步,这一阶段的目的是确保Class 文件的字节 流中包含的信息符合《 Java虚拟机 规范》的全部约束要求,保证这些信 息被当作代码运行后不会危害虚拟机自身的安全。
        验证选项: 文件格式验证    字节码验证    符号引用验证...

3) 准备

        准备阶段是正式为类中定义的变量(即静态变量,被static 修饰的变量)分配内存并设置类变量初始值 的阶段。
  比如此时有这样一行代码:
        public static int value = 123;
        它是初始化 value int 值为 0 ,而非 123

4) 解析

         解析阶段是 Java 虚拟机将常量池内的符号引用替换为直接引用的过程,也就是初始化常量的过程。

5) 初始化

        初始化阶段,Java 虚拟机真正开始执行类中编写的 Java 程序代码,将主导权移交给应用程序。初始化阶段就是执行类构造器方法的过程。

② 双亲委派模型

        如果一个类加载器收到了类加载的请求,它首先不会自己去尝试加载这个类,而是把这个请求委派给父 类加载器去完成,每一个层次的类加载器都是如此,因此所有的加载请求最 终都应该传送到最顶层的启 动类加载器中,只有当父加载器反馈自己无 法完成这个加载请求(它的搜索范围中没有找到所需的类) 时,子加载器才会尝试自己去完成加载。

双亲委派模型的优点

        1. 避免重复加载类:比如 A 类和 B 类都有一个父类 C 类,那么当 A 启动时就会将 C 类加载起来,那 么在 B 类进行加载时就不需要在重复加载 C 类了。
        2. 安全性:使用双亲委派模型也可以保证了 Java 的核心 API 不被篡改,如果没有使用双亲委派模 型,而是每个类加载器加载自己的话就会出现一些问题,比如我们编写一个称为 java.lang.Object 类的话,那么程序运行的时候,系统就会出现多个不同的 Object 类,而有些 Object 类又是用户 自己提供的因此安全性就不能得到保证了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/526346.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

蓝桥杯大赛软件python赛道真题:蛇形填数

真题链接:https://www.lanqiao.cn/problems/594/learning/ 题目描述: 本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。 如下图所示,小明用从1开始的正整数“蛇形”填充无限大的矩阵。 1 2 6 …

最简单的基于 FFmpeg 的内存读写的例子:内存转码器

最简单的基于 FFmpeg 的内存读写的例子:内存转码器 最简单的基于 FFmpeg 的内存读写的例子:内存转码器正文源程序结果工程文件下载参考链接 最简单的基于 FFmpeg 的内存读写的例子:内存转码器 参考雷霄骅博士的文章,链接&#xf…

【脚本玩漆黑的魅影】全自动丢球

文章目录 原理全部代码 原理 启动后截图。 丢球以后再截图。 如果两图一致,说明没成功,读档重来。 如果两图不一致,说明成功了。 while True:press(A)time.sleep(2)if is_same_img(ImageGrab.grab(), data_img):press(save2)else:break全部…

让Putty支持Tab页(多连接管理)

让Putty支持Tab页(多连接管理) 1 介绍2 PuTTY缺陷3 支持Tab页4 支持用户名和密码保存 1 介绍 PuTTY是一个Telnet、SSH、rlogin、纯TCP以及串行接口连接软件。PuTTY为一开放源代码软件,主要由Simon Tatham维护,使用MIT licence授权…

Redis特性与应用场景

Redis是一个在内存中存储数据的中间件,用于作为数据库,用于作为数据缓存,在分布式系统中能够发挥重要作用。 Redis的特性 1.In-memory data structures: MySQL使用表的方式存储数据,这意味着数据通常存储在硬盘上,并且…

JavaEE进阶(15)Spring原理:Bean的作用域、Bean的生命周期、Spring Boot自动配置(加载Bean、SpringBoot原理分析)

接上次博客:JavaEE进阶(14)Linux基本使用和程序部署(博客系统部署)-CSDN博客 目录 关于Bean的作用域 概念 Bean的作用域 Bean的生命周期 源码阅读 Spring Boot自动配置 Spring 加载Bean 问题描述 原因分析 …

IM6ULL学习总结(四-七-1)输入系统应用编程

第7章 输入系统应用编程 7.1 什么是输入系统 ⚫ 先来了解什么是输入设备? 常见的输入设备有键盘、鼠标、遥控杆、书写板、触摸屏等等,用户通过这些输入设备与 Linux 系统进行数据交换。 ⚫ 什么是输入系统? 输入设备种类繁多,能否统一它们的…

网络触手获取天气数据存入mysql 项目

首先这个案例不一定能直接拿来用,虽然我觉得可以但是里面肯定有一些我没考虑到的地方。 有问题评论或者私信我: 这个案例适合我这种学生小白 获取天气数据网址: https://lishi.tianqi.com/xianyang/202201.html 网络触手获取天气数据代码直…

指针篇章-(冒泡排序详解)

冒泡排序 图解 tmp图解 内容图解 每次循环的次数减少 for循环详解 冒泡排序是一种简单的排序算法,它重复地遍历要排序的数列, 一次比较两个元素,如果它们的顺序错误就把它们交换过来。 遍历数列的工作是重复地进行直到没有再需要交换&…

考研复习C语言初阶(4)+标记和BFS展开的扫雷游戏

目录 1. 一维数组的创建和初始化。 1.1 数组的创建 1.2 数组的初始化 1.3 一维数组的使用 1.4 一维数组在内存中的存储 2. 二维数组的创建和初始化 2.1 二维数组的创建 2.2 二维数组的初始化 2.3 二维数组的使用 2.4 二维数组在内存中的存储 3. 数组越界 4. 冒泡…

git学习(创建项目提交代码)

操作步骤如下 git init //初始化git remote add origin https://gitee.com/aydvvs.git //建立连接git remote -v //查看git add . //添加到暂存区git push 返送到暂存区git status // 查看提交代码git commit -m初次提交git push -u origin "master"//提交远程分支 …

图像处理与图像分析—图像的读入(C语言)

学习将会依据教材图像处理与图像分析基础(C/C)版内容展开 什么是数字图像处理 一副图像可以定义为一个二维函数 f(x,y) ,其中 x 和 y 是空间(平面)坐标,任意一对空间坐标 (x,y) 处的幅度值 &am…