Java的结构与运行机制

2024-05-25 17:04
文章标签 java 结构 运行机制

本文主要是介绍Java的结构与运行机制,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1. JDK JRE JVM三者的区别

  • JDK(Java Development Kit):Java开发工具包

    JDK包含JRE,还包括其他例如:编译器(javac)、javadoc、jar等,JDK是能够创建和编译程序的。

  • JRE(Java runtime environment):Java运行环境

    JRE是运行已编译Java程序所需要的所有内容的集合,包括JVM,java类库,java命令和其他基础构建,JRE不能够创建和编译程序。

  • JVM(Java Virtual Machine):Java虚拟机

    JVM是运行java字节码1的虚拟机,JVM有针对不同系统的特定实现(这是因为不同操作系统二进制所代表的不完全相同),目的是使用相同的字节码,在不同的操作系统上都能给出相同的结果,如下图所示

    在这里插入图片描述

JDK、JRE、JVM三者之间的关系
在这里插入图片描述

Java文件在三者之间的流转
在这里插入图片描述

2. Java的运行机制(宏观)

  1. 编译:JDK调用javac工具将.java文件编译成.class文件
    如果在编译时该类所依赖的类还没有被编译则会自动编译所依赖的类并引用
    如果找不到所依赖的类则会报Can't found sysbol的异常

  2. 运行(启动JVM进程):
    类加载的生命周期:加载-->验证-->准备-->解析(验证、准备、解析称为类的连接)-->初始化-->使用-->卸载

    1. 加载:读取class文件到内存的过程

      • 加载.class文件
      • 将class文件的信息存储到方法区
      • 生成一个引用对象(java.lang.Class)
    2. 检验合格性:分为四个阶段
      格式验证:在加载阶段检查字节流是否符合class文件规范
      .class文件是否以魔数(Magic Number)0XCAFEBABE开头
      小版本号Minor version和大版本号Major version
      常量池中常量是否有不支持类型
      Constant_Utf8_info型的常量中是否有不符合UTF-8编码的数据
      class文件中各个部分及文件本身是否有被删除的或附加的其他信息
      ……
      元数据验证:进行字节码语义分析
      检查这个类是否有父类(除了java.lang.Object之外,所有的类都应该有父类)
      这个类的父类是否继承了不允许被继承的类(final修饰的类)
      如果这个类不是抽象类,是否实现了其父类或接口之中要求实现的所有方法
      类中的字段、方法是否与父类产生了矛盾(例如覆盖了父类的final字段,或者不符合规则的方法重载)
      ……
      字节码验证:通过数据流分析和控制流分析,确定程序语法是否合法,是否符合逻辑,是最复杂的验证阶段
      保证任意时刻操作数栈的数据类型与指令代码序列都能配合工作,例如不会出现类似于在操作栈上放置一个int类型的数据,使用时却是按long类型来载入本地的变量表中这样的情况
      保证任何跳转指令都不会跳转到方法体以外的字节码指令上
      保证方法体中的类型转换总是有效的,例如可以把一个子类对象赋值给父类数据类型,这是安全的,但是把一个父类对象赋值给子类数据类型,甚至把对象赋值给与它毫不相关的数据类型,这是危险的,不合法的
      ……
      符号引用验证:
      符号引用中通过字符串描述的全限定名是否能找到对应的类
      在指定的类中是否存在符合方法的字段描述符及简单名称所描述的方法和字段
      符号引用中的类、字段、方法的可访问性—检查权限,验证可被当前类访问
      ……
      由JVM校验.class文件是否符合规范,为了防止代码危害虚拟机本身以及底层系统

    3. 准备:类变量分配内存,在分配内存的过程中,类变量就有了默认值
      为类变量分配内存并设置类变量初始值(默认值,不是赋值),这些类变量所使用的内存全都在方法区进行分配(不包括实例变量:实例变量会在对象实例化随着对象分配到Java堆中)

    4. 解析:将class常量池内的符号引用替换为直接引用的过程
      符号引用:就是字符串,通过字符串中的信息就能直接找到对应的类的数据(只需要无分歧对应数据位置即可)
      直接引用:将符号引用转化为直接引用是因为直接引用是JVM虚拟机可以直接使用的,是虚拟机可读的地址信息,是直接指向目标的指针,不同的JVM虚拟机解析出来的直接地址是不同的,一旦出现直接地址就意味着该目标已经存在于内存中
      如果符合规范就通过类加载器加载到JVM中运行得出结果

    5. 初始化:按照程序代码进行初始化,对数据进行赋值
      类的执行
      JVM主要是在程序第一次运行时,不得不使用类的时候才会立即加载并生成一个java.lang.Class对象,并存在方法区,且只加载一次,这就是为什么实例变量和静态方法只执行一次的原因,执行代码的过程是JVM解释.class文件给操作系统的过程
      注意:.class文件并不能直接与操作系统进行交互,而是通过JVM这个中间层间接与操作系统进行交互
      仅有JVM是不能解释.class文件的,必须是jvm通过调用一个lib类库,而jre就包含这个lib类库

Java的main方法为什么这么写

  1. public:设置访问权限,因为main方法被作为一个主方法,需要且必须被直接访问

  2. static:在JVM中没有实例化main所在的类,而是直接通过类名.main()的方式进行调用的,所以如果不写staticJVM就无法访问到main方法

  3. void:main方法不能有返回值,因为,jvm就算接收到返回值,它返回给谁?所以main中不能存在返回值,包括所有直接对接到JVM层的方法都不能有返回值

  4. String[] args:是用于在main方法执行前接收命令行参数的,作用主要是开发过程无数据情况下以命令行数据进行测试,作用效果不大,但是是规定

JVM在将类字节码读到内存中后,会找到加载的类中的主类,然后在主类中找到main方法之后,将main线程压栈到线程栈中执行main方法

new对象的底层存储

以Hello hello=new Hello()为例

  1. 对象声明:Hello hello
    中开辟一个地址空间,用于存放声明的对象

  2. 创建对象:new Hello()
    1)申请内存空间,将Hello类的相关信息(实例变量,实例方法等)加载到堆内存中
    2)执行构造方法就是<init>方法

  3. 使声明的对象与堆内存中的信息产生关联:
    即将堆内存中的地址赋值给栈中声明的对象,由声明的对象携带这个地址指向堆内存对象信息

堆内存中开辟对象的结构是什么?

  1. 头部信息
    1)偏移值(对齐填充)
    2)持有指向方法区的指针
    3)描述信息(持有当前对象锁的线程id和持有对象锁线程的个数,在GC中存活的生命周期,偏向锁2的标志)
  2. 实例信息
    实例信息为对象的属性和行为,后续会进行详细的解释,目前可以理解为:你定义的类的信息会加载到堆内存中的实例信息部分

  1. JVM能理解的代码就叫做字节码,文件以.class结尾,不面向任何特定的处理器,只面向JVM虚拟机通过字节码的方式,Java语言成功解决了传统解释型语言执行效率低的问题,同时保留了解释型语言可移植的特性虽然执行效率低于C/C++等语言,但是在切换操作系统的情况下,字节码文件无需重新编译,即可运行。 ↩︎

  2. 什么是偏向锁:当线程已经对此对象加锁后,执行完毕,如果下一次访问该线程也是上一次的线程,那么不对此线程重新上锁 ↩︎

这篇关于Java的结构与运行机制的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1002102

相关文章

详解Java如何向http/https接口发出请求

《详解Java如何向http/https接口发出请求》这篇文章主要为大家详细介绍了Java如何实现向http/https接口发出请求,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 用Java发送web请求所用到的包都在java.net下,在具体使用时可以用如下代码,你可以把它封装成一

SpringBoot使用Apache Tika检测敏感信息

《SpringBoot使用ApacheTika检测敏感信息》ApacheTika是一个功能强大的内容分析工具,它能够从多种文件格式中提取文本、元数据以及其他结构化信息,下面我们来看看如何使用Ap... 目录Tika 主要特性1. 多格式支持2. 自动文件类型检测3. 文本和元数据提取4. 支持 OCR(光学

Java内存泄漏问题的排查、优化与最佳实践

《Java内存泄漏问题的排查、优化与最佳实践》在Java开发中,内存泄漏是一个常见且令人头疼的问题,内存泄漏指的是程序在运行过程中,已经不再使用的对象没有被及时释放,从而导致内存占用不断增加,最终... 目录引言1. 什么是内存泄漏?常见的内存泄漏情况2. 如何排查 Java 中的内存泄漏?2.1 使用 J

JAVA系统中Spring Boot应用程序的配置文件application.yml使用详解

《JAVA系统中SpringBoot应用程序的配置文件application.yml使用详解》:本文主要介绍JAVA系统中SpringBoot应用程序的配置文件application.yml的... 目录文件路径文件内容解释1. Server 配置2. Spring 配置3. Logging 配置4. Ma

Java 字符数组转字符串的常用方法

《Java字符数组转字符串的常用方法》文章总结了在Java中将字符数组转换为字符串的几种常用方法,包括使用String构造函数、String.valueOf()方法、StringBuilder以及A... 目录1. 使用String构造函数1.1 基本转换方法1.2 注意事项2. 使用String.valu

java脚本使用不同版本jdk的说明介绍

《java脚本使用不同版本jdk的说明介绍》本文介绍了在Java中执行JavaScript脚本的几种方式,包括使用ScriptEngine、Nashorn和GraalVM,ScriptEngine适用... 目录Java脚本使用不同版本jdk的说明1.使用ScriptEngine执行javascript2.

Spring MVC如何设置响应

《SpringMVC如何设置响应》本文介绍了如何在Spring框架中设置响应,并通过不同的注解返回静态页面、HTML片段和JSON数据,此外,还讲解了如何设置响应的状态码和Header... 目录1. 返回静态页面1.1 Spring 默认扫描路径1.2 @RestController2. 返回 html2

Spring常见错误之Web嵌套对象校验失效解决办法

《Spring常见错误之Web嵌套对象校验失效解决办法》:本文主要介绍Spring常见错误之Web嵌套对象校验失效解决的相关资料,通过在Phone对象上添加@Valid注解,问题得以解决,需要的朋... 目录问题复现案例解析问题修正总结  问题复现当开发一个学籍管理系统时,我们会提供了一个 API 接口去

Java操作ElasticSearch的实例详解

《Java操作ElasticSearch的实例详解》Elasticsearch是一个分布式的搜索和分析引擎,广泛用于全文搜索、日志分析等场景,本文将介绍如何在Java应用中使用Elastics... 目录简介环境准备1. 安装 Elasticsearch2. 添加依赖连接 Elasticsearch1. 创

Spring核心思想之浅谈IoC容器与依赖倒置(DI)

《Spring核心思想之浅谈IoC容器与依赖倒置(DI)》文章介绍了Spring的IoC和DI机制,以及MyBatis的动态代理,通过注解和反射,Spring能够自动管理对象的创建和依赖注入,而MyB... 目录一、控制反转 IoC二、依赖倒置 DI1. 详细概念2. Spring 中 DI 的实现原理三、