JVM(Java虚拟机)

文章目录

    • 一、JVM简介
      • 1.1 JVM概念
      • 1.2 什么是Java虚拟机呢?Java虚拟机的好处是什么呢?
    • 二、JVM整体组成部分
    • 三、类加载器
      • 3.1 类加载子系统
      • 3.2 类加载过程
        • 3.2.1 装载(Load)
        • 3.2.2 链接(Link)
        • 3.2.3 初始化(Initialize)
    • 四、运行时数据区
      • 4.1 方法区(Method Area)
      • 4.2 Java堆(Java Heap)
      • 4.3 程序计数器(Program Counter Register)
      • 4.4 Java虚拟机栈(Java Virtual Machine Stacks)
      • 4.5 本地方法栈(Native Method Stack)
    • 五、 执行引擎
      • 5.1 概述
      • 5.2 什么是解释器?什么是 JIT 编译器?
    • 六、 本地方法接口
      • 6.1 什么是本地方法
      • 6.2 为什么要使用 Native Method
    • 七、 垃圾回收
      • 7.1 垃圾回收概述
      • 7.2 新生代、老年代、永久代(方法区)的区别
      • 7.3 JVM的垃圾回收机制
      • 7.4 Minor GC、Major GC、Full GC区别及触发条件
      • 7.5 垃圾收集器
        • 7.5.1 什么是垃圾收集器?
        • 7.5.2 垃圾回收器详解


一、JVM简介

1.1 JVM概念

JVM是Java Virtual Machine(Java虚拟机)的缩写。

1.2 什么是Java虚拟机呢?Java虚拟机的好处是什么呢?

虚拟机是一种抽象化的计算机,通过在实际的计算机上仿真模拟各种计算机功能来实现的。Java虚拟机有自己完善的硬体架构,如处理器、堆栈、寄存器等,还具有相应的指令系统。Java虚拟机屏蔽了与具体操作系统平台相关的信息,使得Java程序只需生成在Java虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改地运行。
简单来说JVM是用来解析和运行Java程序的。
Java语言的一个非常重要的特点就是与平台的无关性。而使用Java虚拟机是实现这一特点的关键。一般的高级语言如果要在不同的平台上运行,至少需要编译成不同的目标代码。而引入Java语言虚拟机后,Java语言在不同平台上运行时不需要重新编译。Java语言使用Java虚拟机屏蔽了与具体平台相关的信息,使得Java语言编译程序只需生成在Java虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改地运行。Java虚拟机在执行字节码时,把字节码解释成具体平台上的机器指令执行。这就是Java的能够一次编译,到处运行的原因。

二、JVM整体组成部分

  1. 类加载器(ClassLoader)
  2. 运行时数据区(Runtime Data Area)
  3. 执行引擎(Execution Engine)
  4. 本地库接口(Native Interface)

三、类加载器

3.1 类加载子系统

在这里插入图片描述
类加载子系统负责从文件系统或者网络中加载class文件。classLoader只负责class文件的加载,至于它是否可以裕兴,则由Execution Engine决定。
加载的类信息存放于一块称为方法区的内存空间。
在这里插入图片描述
class file 存在于硬盘上,可以理解为设计师画在纸上的模板,而最终这个模板在执行的时候是要加载 JVM 当中来,根据这个模板实例化出 n 个实例。
class file 加载到 JVM 中,被称为 DNA 元数据模板. 此过程就要有一个运输工具(类加载器 Class Loader),扮演一个快递员的角色。

3.2 类加载过程

在这里插入图片描述

3.2.1 装载(Load)
  1. 通过类名(地址)获取此类的二进制字节流。
  2. 将这个字节流所代表的静态存储结构转换为方法区(元空间)的运行时结构。
  3. 在内存中生成一个代表这个类的java.lang.class对象,作为这个类的各种数据的访问入口。
3.2.2 链接(Link)
  1. 验证:检验被加载的类是否有正确的内部结构,并和其他类协调一致;验证文件格式是否一致;class 文件在文件开头有特定的文件标识(字节码文件都以 CA FE BA BE 标识开头);元数据验证:对字节码描述的信息进行语义分析,以保证其描述的信息符合java 语言规范的要求。
  2. 准备:准备阶段则负责为类的静态属性分配内存,并设置默认初始值;不包含用 final 修饰的 static 常量,在编译时进行初始化。
  3. 解析:将类的二进制数据中的符号引用替换成直接引用(符号引用是 Class 文件的逻辑符号,直接引用指向的方法区中某一个地址)
3.2.3 初始化(Initialize)

  对类的静态变量,静态代码块执行初始化操作 执行了Clinit方法

四、运行时数据区

在这里插入图片描述

4.1 方法区(Method Area)

  方法区是所有线程共享的内存区域,它用于存储已被Java虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。
它有个别命叫Non-Heap(非堆)。当方法区无法满足内存分配需求时,抛出OutOfMemoryError异常。

4.2 Java堆(Java Heap)

  • java堆是java虚拟机所管理的内存中最大的一块,是被所有线程共享的一块内存区域,在虚拟机启动时创建。此内存区域的唯一目的就是存放对象实例。
  • 在Java虚拟机规范中的描述是:所有的对象实例以及数组都要在堆上分配。
  • java堆是垃圾收集器管理的主要区域,因此也被成为“GC堆”。

4.3 程序计数器(Program Counter Register)

  • 程序计数器是一块较小的内存空间,它可以看作是:保存当前线程所正在执行的字节码指令的地址(行号)
  • 由于Java虚拟机的多线程是通过线程轮流切换并分配处理器执行时间的方式来实现的,一个处理器都只会执行一条线程中的指令。因此,为了线程切换后能恢复到正确的执行位置,每条线程都有一个独立的程序计数器,各个线程之间计数器互不影响,独立存储。称之为“线程私有”的内存。程序计数器内存区域是虚拟机中唯一没有规定OutOfMemoryError情况的区域。

4.4 Java虚拟机栈(Java Virtual Machine Stacks)

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

4.5 本地方法栈(Native Method Stack)

  • 本地方法栈很好理解,他很栈很像,只不过方法上带了 native 关键字的栈字
  • 它是虚拟机栈为虚拟机执行Java方法(也就是字节码)的服务
  • native关键字的方法是看不到的,必须要去oracle官网去下载才可以看的到,而且native关键字修饰的大部分源码都是C和C++的代码。
  • 同理可得,本地方法栈中就是C和C++的代码

五、 执行引擎

5.1 概述

  • 执行引擎是 Java 虚拟机核心的组成部分之一。
  • JVM 的主要任务是负责装载字节码到其内部,但字节码并不能够直接运行在操作系统之上,因为字节码指令并非等价于本地机器指令,它内部包含的仅仅只是一些能够被 JVM 所识别的字节码指令、符号表,以及其他辅助信息。
    那么,如果想要让一个 Java 程序运行起来,执行引擎(Execution Engine)的任务就是将字节码指令解释/编译为对应平台上的本地机器指令才可以。简单来说,JVM 中的执行引擎充当了将高级语言翻译为机器语言的译者。

5.2 什么是解释器?什么是 JIT 编译器?

  • 解释器: 当 Java虚拟机启动时会根据预定义的规范对字节码采用逐行解释的方式执行,将每条字节码文件中的内容“翻译”为对应平台的本地机器指令执行。
  • JIT(Just In Time Compiler)编译器:
    就是虚拟机将源代码一次性直接编译成和本地机器平台相关的机器语言,但并不是马上执行。

六、 本地方法接口

6.1 什么是本地方法

  • 简单来讲, 一个 Native Method 就是一个 java 调用非 java 代码的接口 ,一个Native Method是这样一个 java 方法:该方法的底层实现由非 Java 语言实现,比如 C。这个特征并非 java特有,很多其他的编程语言都有这一机制在定义一个 native method 时,并不提供实现体(有些像定义一个 Java interface),因为其实现体是由非 java 语言在外面实现的。
  • 关键字 native 可以与其他所有的 java 标识符连用,但是 abstract 除外。

6.2 为什么要使用 Native Method

  Java 使用起来非常方便,然而有些层次的任务用 java 实现起来不容易,或者我们对程序的效率很在意时,问题就来了。

  • 与 java 环境外交互。
      有时 java 应用需要与 java 外面的环境交互,这是本地方法存在的主要原因。 你可以想想 java 需要与一些底层系统,如某些硬件交换信息时的情况。本地方法正式这样的一种交流机制:它为我们提供了一个非常简洁的接口,而且我们无需去了解java 应用之外的繁琐细节。
  • Sun 的解释器是用 C 实现的,这使得它能像一些普通的 C 一样与外部交互。
      jre大部分是用 java 实现的,它也通过一些本地方法与外界交互。例如:类 java.lang.Thread 的 setPriority()方法是用 Java 实现的,但是它实现调用的是该类里的本地方法 setPriority0()。

七、 垃圾回收

7.1 垃圾回收概述

  • Java 和 C++语言的区别,就在于垃圾收集技术和内存动态分配上,C++语言没有垃圾收集技术,需要程序员手动的收集。
  • 关于垃圾收集有三个经典问题:
    哪些内存需要回收?
    什么时候回收?
    如何回收?

7.2 新生代、老年代、永久代(方法区)的区别

  • Java 中的堆是 JVM 所管理的最大的一块内存空间,主要用于存放各种类的实例对象。
  • 在 Java 中,堆被划分成两个不同的区域:新生代 ( Young )、老年代 ( Old )。

7.3 JVM的垃圾回收机制

  垃圾回收机制简称GC,GC主要用于Java堆的管理。Java 中的堆是 JVM 所管理的最大的一块内存空间,主要用于存放各种类的实例对象。
  程序在运行过程中,会产生大量的内存垃圾(一些没有引用指向的内存对象都属于内存垃圾,因为这些对象已经无法访问,程序用不了它们了,对程序而言它们已经死亡),为了确保程序运行时的性能,java虚拟机在程序运行的过程中不断地进行自动的垃圾回收(GC)。

7.4 Minor GC、Major GC、Full GC区别及触发条件

Minor GC是新生代GC,指的是发生在新生代的垃圾收集动作。由于java对象大都是朝生夕死的,所以Minor GC非常频繁,一般回收速度也比较快。

Major GC是老年代GC,指的是发生在老年代的GC,通常执行Major GC会连着Minor GC一起执行。Major GC的速度要比Minor GC慢的多。

Full GC是清理整个堆空间,包括年轻代和老年代

Minor GC 触发条件一般为:

  • eden区满时,触发MinorGC。即申请一个对象时,发现eden区不够用,则触发一次MinorGC。
  • ​ 新创建的对象大小 > Eden所剩空间

Major GC和Full GC 触发条件一般为:

  Major GC通常是跟full GC是等价的

  • 每次晋升到老年代的对象平均大小>老年代剩余空间
  • MinorGC后存活的对象超过了老年代剩余空间
  • 永久代空间不足

7.5 垃圾收集器

7.5.1 什么是垃圾收集器?
  • 垃圾收集器是垃圾回收算法(引用计数法、标记清楚法、标记整理法、复制算法)的具体实现,不同垃圾收集器、不同版本的JVM所提供的垃圾收集器可能会有很在差别。
  • 这里以JDK8为准:

在这里插入图片描述
图中展示了7种不同分代的收集器:
Serial、ParNew、Parallel Scavenge、CMS、Serial Old、Parallel Old、G1
而它们所处区域,则表明其是属于新生代还是老年代的收集器:

  • 新生代收集器:Serial、ParNew、Parallel Scavenge
  • 老年代收集器:CMS、Serial Old、Parallel Old
  • 整堆收集器:G1
7.5.2 垃圾回收器详解
  • Serial 收集器:新生代。发展历史最悠久的收集器。它是一个单线程收集器,它只会使用一个 CPU或者线程去完成垃圾收集工作,而且在它进行垃圾收集时,必须暂停其他所有的工作线程,直到它收集结束。
  • ParNew 收集器:新生代。Serial 的多线程版本,即同时启动多个线程去进行垃圾收集。
  • Parallel Scavenge 收集器:新生代。和 ParNew 的关注点不一样,该收集器更关注吞吐量,尽快地完成计算任务。
  • Serial Old 收集器:Serial 的老年代版本,使用标记 - 整理算法。
  • Parallnel old 收集器,多线程:Parallel 的老年代版本,使用标记 - 整理算法。
  • CMS 收集器:老年代。是一种以获取最短回收停顿时间为目标的收集器,适用于互联网站或者 B/S 系统的服务端上。
  • G1收集器:分代收集器。当今收集器技术发展最前沿成果之一,是一款面向服务端应用的垃圾收集器。G1可以说是CMS的终极改进版,解决了CMS内存碎片、更多的内存空间登问题。虽然流程与CMS比较相似,但底层的原理已是完全不同。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

stack 与 queue 与 priority_queue 与 仿函数 与 模板进阶

目录 stack queue deque priority_queue 使用 模拟实现 仿函数 仿函数的用法 仿函数的意义 模板进阶 非类型模板参数 模板特化 类模板特化的用法 类模板特化的意义 函数模板特化的用法 模板的分离编译 模板分离编译报错的原因 ​解决方法 模板总结 栈、队列…

Git安装教程(图文安装)

Git Bash是git(版本管理器)中提供的一个命令行工具,外观类似于Windows系统内置的cmd命令行工具。 可以将Git Bash看作是一个终端模拟器,它提供了类似于Linux和Unix系统下Bash Shell环境的功能。通过Git Bash,用户可以在Windows系统中运行基于…

【数据处理包Pandas】DataFrame对象的合并

目录 前言一、回顾Numpy数组的合并二、concat方法合并DataFrame对象三、append方法的使用四、merge方法合并DataFrame对象(一)比较merge与concat(二)参数on、left_on和right_on的用法(三)合并时四种不同的连…

c# wpf template ItemsPanel 简单试验

1.概要 2.代码 <Window x:Class"WpfApp2.Window9"xmlns"http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x"http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d"http://schemas.microsoft.com/expression/blend/…

软件测试(Junit5 单元测试框架)(五)

1. Junit单元测试框架 Junit 是 Java 的一个单元测试框架, 使用Selenium写自动化测试用例, 使用Junit 管理写好的测试用例. 2. 注解&#xff1a; Test 表示当前的这个方法是一个测试用例. 示例: 添加依赖 <!-- https://mvnrepository.com/artifact/org.junit.jupiter/junit-…

[译] 教你如何用 Flutter 的 GestureDetector 构建自定义滑块

这个控件非常简单&#xff0c;我们接收完成的百分比值&#xff0c;以及正面和背面部分的颜色。主 Container 将背面颜色作为背景&#xff0c;我们将绘制正面部分去覆盖它。它的子节点是 Row&#xff0c;虽然它只包含一个子节点&#xff0c;但我保留了它&#xff0c;方便你添加另…

impala使用round函数保留小数失效

问题描述如标题所示 1.理论情况: round()函数,是用来做四舍五入的,比如:select round(2.126,2) 结果为:2.132.异常情况: 但是有时候会出现一些意料之外的情况,比如:select round(1/3,3) 结果为:0.33300000000000002正确的应该是:0.333截图效果示例如下: 3.解决办…

51之LCD1602与模块化编程

LCD1602&#xff0c;即我们开发板上附赠的那个液晶显示屏&#xff0c;我们通常可以使用这个液晶显示屏用来做调试工具&#xff0c;我们使用一下江科大提供的关于这个LCD1602的代码&#xff0c;用来为我们提供了类似C语言标准库里面的printf函数的用法&#xff0c;只是这个更加复…

非关系型数据库-----------探索 Redis高可用 、持久化、性能管理

目录 一、Redis 高可用 1.1什么是高可用 1.2Redis的高可用技术 二、 Redis 持久化 2.1持久化的功能 2.2Redis 提供两种方式进行持久化 三、Redis 持久化之----------RDB 3.1触发条件 3.1.1手动触发 3.1.2自动触发 3.1.3其他自动触发机制 3.2执行流程 3.3启动时加载…

AssetBundle在移动设备上丢失

1&#xff09;AssetBundle在移动设备上丢失 2&#xff09;Unity云渲染插件RenderStreaming&#xff0c;如何实现多用户分别有独立的操作 3&#xff09;如何在圆柱体类型的地图中编程玩家的输入 4&#xff09;Mixamo动画的根运动问题 这是第380篇UWA技术知识分享的推送&#xff…

如何处理ubuntu22.04LTS安装过程中出现“Daemons using outdated libraries”提示

Ubuntu 22.04 LTS 中使用命令行升级软件或安装任何新软件时&#xff0c;您可能收到“Daemons using outdated libraries”&#xff0c;“Which services should be restarted?”的提示&#xff0c;提示下面列出备选的重启服务&#xff0c;如下。 使用以下命令&#xff0c;能够…

盒子模型和伪元素

一.盒子模型的理解 我们平常在布局的时候,少不了盒子模型,今天讲解一下对盒子模型的理解。 理解:我们可以把盒子模型比作一个装着快递的包裹:里面的东西可以比作是内容,盒子里面的填充物可以比作是padding 外层的包装纸线条,可以比作是border&#xff0c;这个快递离另外个快递…

PS从入门到精通视频各类教程整理全集,包含素材、作业等(9)复发

PS从入门到精通视频各类教程整理全集&#xff0c;包含素材、作业等 最新PS以及插件合集&#xff0c;可在我以往文章中找到 由于阿里云盘有分享次受限制和文件大小限制&#xff0c;今天先分享到这里&#xff0c;后续持续更新 第一课 ——第三课素材文件 https://www.alipan.c…

20230405让WIN11暂停更新365天(暂停更新35天)

20230405让WIN11暂停更新365天&#xff08;暂停更新35天&#xff09; 2024/4/5 20:34 缘起&#xff0c;备用的笔记本电脑只要一开机&#xff0c;就会被比尔盖茨/微软提醒去更新/升级&#xff01; 不胜其烦&#xff01; 虽然可以在设置里设置暂停更新35天。但是也是不胜其扰&…

蓝桥杯杯赛之深度优先搜索优化《1.分成互质组》 《 2.小猫爬山》【dfs】【深度搜索剪枝优化】【搜索顺序】

文章目录 思想例题1. 分成互质组题目链接题目描述【解法一】【解法二】 2. 小猫爬山题目链接题目描述输入样例&#xff1a;输出样例&#xff1a;【思路】【WA代码】【AC代码】 思想 本质为两种搜索顺序&#xff1a; 枚举当前元素可以放入哪一组枚举每一组可以放入哪些元素 操…

解决windows下Qt Creator显示界面过大的问题

&#x1f40c;博主主页&#xff1a;&#x1f40c;​倔强的大蜗牛&#x1f40c;​ &#x1f4da;专栏分类&#xff1a;QT❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ 目录 问题描述 解决方法 1、右击此电脑--->属性 2、点击高级系统设置--->点击环境变量 3、 找到系…

YOLOv3

YOLOv3 论文简介论文内容1. 采用darknet53FPN结构2. 边框预测保持与YOLOv2保持一致3. 沿用YOLOv2 kmeans生成先验anchors4.类别预测改为多分类格式 论文简介 论文&#xff1a;《YOLOv3: An Incremental Improvement》 作者&#xff1a;Joseph Redmon, Ali Farhadi 论文下载地址…

使用 Kafka 保证消息不丢失的策略及原理解析

✨✨祝屏幕前的小伙伴们每天都有好运相伴左右&#xff0c;一定要天天开心&#xff01;✨✨ &#x1f388;&#x1f388;作者主页&#xff1a; 喔的嘛呀&#x1f388;&#x1f388; 目录 一、引言 二. 持久化存储 2.1持久化存储原理&#xff1a; 2.2使用示例&#xff1a; …

7.java openCV4.x 入门-Mat之转换、重塑与计算

专栏简介 &#x1f492;个人主页 &#x1f4f0;专栏目录 点击上方查看更多内容 &#x1f4d6;心灵鸡汤&#x1f4d6;我们唯一拥有的就是今天&#xff0c;唯一能把握的也是今天建议把本文当作笔记来看&#xff0c;据说专栏目录里面有相应视频&#x1f92b; &#x1f9ed;文…

2024HW --->反序列化漏洞!

对于反序列化&#xff0c;这个漏洞也是常用的&#xff0c;不过涉及到的方面非常非常广&#xff0c;比其他漏洞也难很多 于是本篇文章就分成PHP和JAVA的反序列化来讲讲 1.反序列化 想要理解反序列化&#xff0c;首先就要理解序列化 序列化&#xff1a;把对象转换为字节序列的过…