• Java的虚拟机JVM介绍(面试屡屡碰壁学习记录一下)


            简单介绍一下java程序的运行流程

    1. .java文件
    2. .class文件
    3. jvm识别.class

    下面就是jvm虚拟机 

    正是有了jvm虚拟机才体现了java语言的跨平台性

             所以说jvm的作用如下:

    java虚拟机是二进制的字节码运行环境,可以运行.class文件。并且解释编译为对应平台的机器指令进行执行。

            特点:

    • 一次编译处处运行
    • 自动内存管理
    • 自动垃圾回收功能

    目前市面上最常见运用最广泛的是HotSpotVm虚拟机

     在虚拟机发展的历程中还有如下的JVM:sun ClassicVM、ExactVm、IBMJ9、AzulVM等等感兴趣的可以去搜索一下,我们主要根据HotSpotVm讲解JVM。

    1.类的加载以及加载过程

            

     通过javac的编译会生成.class

            我们的类加载器就会加载我们电脑磁盘上的class文件,加载到了JVM虚拟机中被称之为DNA原数据模板,存放在方法区中。

            就是这个class文件到达jvm成为原数据模板的过程之中需要通过类加载器实现(ClassLoader)。我们的类加载器相当于运输设备。

    1.1类加载的过程 

    对于加载的过程细分如下

    我们重点解读一下链接 的过程

    • 验证

    目的在于确保class文件的字节流中的信息符合虚拟机的要求,保证正确性不会危害jvm虚拟机的运行。

    4种验证方式:文件格式验证,原数据验证,字节码原则,符号应用验证

    • 准备

    为类的变量分配内存并且设置默认值

    这里不包含final修饰的static,因为final在编译的时候就会分配内存

    这里不会为实例变量分配初始化,类的变量会分配在方法区中,而实例化的变量会随着对象一起分配到java的堆中

    • 解析

    将常量池中的符号引用转换为直接引用过程。

    事实上,解析操作往往会伴随着jvm在执行完成初始化之后进行

    解析的动作主要是针对类或者接口、字段、类方法、接口方法、方法类型等。

    • 初始化

    初始化阶段就是执行类构造器方法的过程

    此方法不需要被定义,是javac编译器字段收集类中的所有类变量的赋值动作和静态代码中的语句进行合并。

     1.2类加载器的分类

    JVM虚拟机支持2中类加载器如下:

    • 引导类加载器(BootstrapClassLoader)
    • 自定义类加载器(User-definedClassloader)

    自定义类加载 器一般指的是由ClassLoader派生出来的类加载器称之为自定义。

    1.3 启动类加载器BootstrapClassLoader

            启动类的加载器Jvm虚拟机自带BootstrapClassLoader

    这个类加载器是用c语言实现的,嵌套在jvm的内部

    他用来加载java的核心类库。

    并没有继承java.lang.classLoader没有父类加载器

    出于安全考虑Bootstarap启动类加载器只会加载包名为java  javax sun等开头的类

    1.4  扩展类加载器(ExtensionClassLoader)

    java语言编写的加载器

    派生于Classloader

    父类是启动类加载器

    从java.ext.dirs系统属性所指向的目录加载类库,或者从jdk的安装目录的jre/lib/ext子目录下加载类库。如果用户自己创建的jar放在此目录下,也会自动由扩展类加载器进行加载。

    1.5应用程序类加载器(AppClassLoader)

    由java语言编写

    派生于ClassLoader

    负责加载变量classpath或者系统属性java.class.path指定路径下的类库

    该类加载器是陈故乡默认的类加载器,一般的java应用类都是又他完成加载的

    1.6用户自定义类加载器

    开发人员可以通过继承ClassLoader类的方式实现

    在jdk1.2之前要求开发人员继承了ClassLoader的时候要重写loaderClass()方法,但是在jdk1.2之后不建议覆盖loaderClass()方法,而是讲加载的逻辑方法写在FindClass()方法之中。

    1.7双亲委派机制

            java虚拟机对class文件采用按需加载的方式,也就是说当需要用到这个类的时候才会将他的class文件加载到内存生成class对象。而且在加载这个对象的class文件的时候,jvm采用的是双亲委派的模式,就是把请求交由父类处理。

    工作原理:

    1. 如果一个类加载器收到请求,他并不会自己去加载,而是把这个请求委托给父类加载器去执行。
    2. 如果父类加载器还有更上一层的父类加载器继续委托,直到最顶层的启动类加载器
    3. 如果父类加载器可以完成加载任务,就返回成功,只有在父类加载器无法完成任务的时候子类加载器才会尝试自己去完成加载任务。

     1.8 补充

     Jvm中判断2个class对象是否为同一个类存在以下条件

    • 类的完整类名一致,包名一致
    • 加载这个类的ClassLoader必须相同

    jvm必须知道一个类型是由启动类加载器加载的还是有用户类型加载器加载的。

           1. 如果一个类型是由用户类加载器加载的,那么jvm会将这个类加载器的一个引用作为类型信息的一部分保存着方法区。

            2.当解析一个类型得到另一个类型的引用的时候,jvm需要保证这两个类型的加载器是相同的。

    java如何使用类

    2.运行时数据区和jvm的基本结构

    2.1 jvm结构

            内存是非常重要的系统资源,建立cpu和硬盘中间仓库桥梁。jvm内存布局规定了java在运行过程中的内存申请、分配、管理的策略。保证了jvm的高效稳定,不同的jvm对于内存的划分和管理机制不同这样我们主要也是HotSpotVm。

    2.2 HotSpotVm 的运行时数据区

    java的虚拟机定义了若干中程序运行时会使用到的运行时数据区,其中有的一线会随着虚拟机的启动二创建,伴随着虚拟机的退出而销毁。另外一些则是与线程一一对应,这些与线程对应的数据区域会随着线程的生命周期而创建消失。

    如下图:

    灰色表示为单独现场私有,红色表示多个线程的共享

    每个线程:独立包括程序计数器,栈、本地栈。

    线程空间共享:堆、堆外内存

    • jvm线程

    ​​​​​​​

     

     

  • 相关阅读:
    使用branch and bound分支定界算法选择UTXO
    Borland Delphi 2005对Delphi语言的支持
    Linux怎么查看group
    300万数据导入导出优化方案,从80s优化到8s(实测)
    redis学习(008 实战:黑马点评:缓存介绍)
    单调栈题目:移掉 K 位数字
    为什么拖拽式表单设计器受欢迎?
    Android基础第十天 | 字节跳动第四届青训营笔记
    Vue项目开发之表单验证&增删改功能
    【Oracle】回滚/闪回误差入数据
  • 原文地址:https://blog.csdn.net/weixin_53472653/article/details/125522971