当前位置: 首页 > news >正文

JVM虚拟机

java文件都是.java

编译之后才是.class

千万不要把.class认为是java的类文件

 

编译的过程是由jdk完成的,和jvm是没有关系的

对就是javac编译器将Java代码翻译成字节码

.class文件就是字节码文件,字节码可以在jvm上运行

 

        我们都知道在 Windows 系统上一个软件包装包是 exe 后缀的,而这个软件包在苹果的 Mac OSX 系统上是无法安装的。类似地,Mac OSX 系统上软件安装包则是 dmg 后缀,同样无法在 Windows 系统上安装。

       为什么不同系统上的软件无法安装,这是因为操作系统底层的实现是不一样的对于 Windows 系统来说,exe 后缀的软件代码最终编译成 Windows 系统能识别的机器码。而 Mac OSX 系统来说,dmg 后缀的软件代码最终编译成 Mac OSX 系统能识别的代码

      而与其他语言不同,Java 语言并不直接将代码编译成与系统有关的机器码,而是编译成一种特定的语言规范,这种语言规范我们称之为字节码。无论 Java 程序要在 Windows 系统,还是 Mac OSX 系统,抑或是 Linux 系统,它首先都得编译成字节码文件,之后才能运行。但即使编译成字节码文件了,各个系统还是无法明白字节码文件的内容,这时候就需要 Java 虚拟机的帮助了。Java 虚拟机会解析字节码文件的内容,并将其翻译为各操作系统能理解的机器码

       很多初学者关于 Java 虚拟机有一个误区,他们会觉得 Java 虚拟机只能运行 Java 代码。但实际上 Java 虚拟机运行的是字节码文件换句话说,如果你用 php 语言写一段代码,并自己用特定编译器能生成符合字节码规范的字节码文件,那么 Java 虚拟机也是可以运行的

    

      Java 虚拟机做的事情就是:按照 Java 虚拟机规范去读取 Class 文件,并按照规定去解析、执行字节码指令,仅此而已

      如果你够牛逼,你完全可以写一个编译器,将 PHP 语言代码编译成符合 Java 虚拟机规范的字节码文件,那么 Java 虚拟机也是可以执行的

      准确地说,Java 虚拟机与字节码文件(Class文件)绑定

      其实 Java 虚拟机就是一个字节码翻译器,它将字节码文件翻译成各个系统对应的机器码,确保字节码文件能在各个系统正确运行。
 

 

jdk、jre和jvm的关系

jdk包含jre,jre包含jvm

 

JVM的组成

类加载器负责程序员和jvm交互,把.class加载到jvm中

运行时数据区是由方法区、栈、堆等共同组成的一个区域

执行引擎负责jvm和操作系统的交互

 

JVM编译器

      在 JVM 中有三个非常重要的编译器,它们分别是:前端编译器、JIT 编译器、AOT 编译器

     前端编译器,最常见的就是我们的 javac 编译器,其将 Java 源代码编译为 Java 字节码文件(我们一般称 javac 编译器为前端编译器,因为其发生在整个编译的前期)

    JIT 即时编译器,最常见的是 HotSpot 虚拟机中的 Client Compiler 和 Server Compiler,其将 Java 字节码编译为本地机器代码

    AOT 编译器则能将源代码直接编译为本地机器码

 

这三种编译器的编译速度和编译质量如下:

  • 编译速度上,解释执行 > AOT 编译器 > JIT 编译器。
  • 编译质量上,JIT 编译器 > AOT 编译器 > 解释执行。

而在 JVM 中,通过这几种不同方式的配合,使得 JVM 的编译质量和运行速度达到最优的状态。

 

JVM内存结构(即运行时数据区)

       其实 Java 虚拟机的内存结构并不是官方的说法,在《Java 虚拟机规范》中用的是「运行时数据区」这个术语。但很多时候这个名词并不是很形象,再加上日积月累的习惯,我们都习惯用虚拟机内存结构这个说法了

       Java 虚拟机的内存结构可以分为公有和私有两部分:

  • 公有指的是所有线程都共享的部分,指的是 Java 堆、方法区、常量池。
  • 私有指的是每个线程的私有数据,包括:PC寄存器、Java 虚拟机栈、本地方法栈

 

JVM 类加载机制

        当 Java 虚拟机将 Java 源码编译为字节码之后,虚拟机便可以将字节码读取进内存,从而进行解析、运行等整个过程,这 个过程我们叫:Java 虚拟机的类加载机制。

       JVM 虚拟机执行 class 字节码的过程可以分为七个阶段:加载、验证、准备、解析、初始化、使用、卸载。

 

加载
      把代码数据加载到内存中

验证
      JVM 对字节码流的校验,只有符合 JVM 字节码规范的文件才能被 JVM 正确执行

准备(重点)
      开始为类变量分配内存并初始化

解析
      JVM 针对类或接口、字段、类方法、接口方法、方法类型、方法句柄和调用点限定符 7 类引用进行解析。这个阶段的主要任务是将其在常量池中的符号引用替换成直接其在内存中的直接引用

初始化(重点)
      到了初始化阶段,用户定义的 Java 程序代码才真正开始执行。在这个阶段,JVM 会根据语句执行顺序对类对象进行初始化

使用
      JVM 开始从入口方法开始执行用户的程序代码

卸载
      当用户程序代码执行完毕后,JVM 便开始销毁创建的 Class 对象,最后负责运行的 JVM 也退出内存

 

JVM 垃圾回收机制

到底谁是垃圾?

      如果一个对象不可能再被引用,那么这个对象就是垃圾,应该被回收。

 

      根据这个思想,我们很容易想到使用引用计数的方法来判断垃圾。在一个对象被引用时加一,被去除引用时减一,这样我们就可以通过判断引用计数是否为零来判断一个对象是否为垃圾。这种方法我们一般称之为「引用计数法」。

     上面的这种方法虽然简单,但是其存在一个致命的问题,那就是循环引用

      A 引用了 B,B 引用了 C,C 引用了 A,它们各自的引用计数都为 1。但是它们三个对象却从未被其他对象引用,只有它们自身互相引用。从垃圾的判断思想来看,它们三个确实是不被其他对象引用的,但是此时它们的引用计数却不为零。这就是引用计数法存在的循环引用问题。

      而现今的 Java 虚拟机判断垃圾对象使用的是:GC Root Tracing 算法。其大概的过程是这样:从 GC Root 出发,所有可达的对象都是存活的对象,而所有不可达的对象都是垃圾

 

 

 

相关文章:

  • MyOS(一):用Java做一个最小的helloworld操作系统内核
  • Windows下Vim
  • 汇编语言
  • SVN服务器端
  • Mavic Mini
  • Chrome浏览器
  • SVN客户端
  • Windows批处理文件bat/cmd
  • IDEA 操作快捷键
  • Python迭代器 iterator(iter next) 生成器 generator(yield) yield
  • Python协程(generator, yield, send)
  • 虚拟机 虚拟硬盘
  • 8086处理器 硬盘
  • 虚拟机快照
  • 虚拟机克隆 将虚拟机导出为 OVF 格式
  • es6
  • iOS仿今日头条、壁纸应用、筛选分类、三方微博、颜色填充等源码
  • Java方法详解
  • Laravel Mix运行时关于es2015报错解决方案
  • Laravel5.4 Queues队列学习
  • nodejs调试方法
  • Python十分钟制作属于你自己的个性logo
  • Swoft 源码剖析 - 代码自动更新机制
  • 搞机器学习要哪些技能
  • 东超科技获得千万级Pre-A轮融资,投资方为中科创星 ...
  • 我们雇佣了一只大猴子...
  • ​Distil-Whisper:比Whisper快6倍,体积小50%的语音识别模型
  • (1)虚拟机的安装与使用,linux系统安装
  • (11)MSP430F5529 定时器B
  • (32位汇编 五)mov/add/sub/and/or/xor/not
  • (cljs/run-at (JSVM. :browser) 搭建刚好可用的开发环境!)
  • (C语言)编写程序将一个4×4的数组进行顺时针旋转90度后输出。
  • (done) NLP “bag-of-words“ 方法 (带有二元分类和多元分类两个例子)词袋模型、BoW
  • (附源码)spring boot基于Java的电影院售票与管理系统毕业设计 011449
  • (经验分享)作为一名普通本科计算机专业学生,我大学四年到底走了多少弯路
  • (亲测成功)在centos7.5上安装kvm,通过VNC远程连接并创建多台ubuntu虚拟机(ubuntu server版本)...
  • (一)Linux+Windows下安装ffmpeg
  • (转)从零实现3D图像引擎:(8)参数化直线与3D平面函数库
  • **PHP分步表单提交思路(分页表单提交)
  • ... 是什么 ?... 有什么用处?
  • .form文件_一篇文章学会文件上传
  • .net 8 发布了,试下微软最近强推的MAUI
  • .NET Framework Client Profile - a Subset of the .NET Framework Redistribution
  • .NET Windows:删除文件夹后立即判断,有可能依然存在
  • .NET 编写一个可以异步等待循环中任何一个部分的 Awaiter
  • .NET性能优化(文摘)
  • [ Linux 长征路第二篇] 基本指令head,tail,date,cal,find,grep,zip,tar,bc,unname
  • [20160902]rm -rf的惨案.txt
  • [BUUCTF NewStarCTF 2023 公开赛道] week3 crypto/pwn
  • [bzoj2957]楼房重建
  • [C#C++]类CLASS
  • [C]整形提升(转载)
  • [CSS]盒子模型
  • [Deep Learning] 神经网络基础
  • [dfs] 图案计数