JVM快速入门


java8虚拟机有什么更新:本地的物理内存(电脑的内存)

前言

例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容。


一、JVM快速入门

位置:JVM是运行在操作系统之上的,它与硬件没有直接的交互

在这里插入图片描述

1.结构图(基本体系结构)

在这里插入图片描述
方法区:存储已被虚拟机加载的类元数据信息(元空间–元模板)

类包括属性 方法–>java元文件 -->编译完变成class文件 -->会变成一个模板(元空间) --> new 俩个对象stu,stu1,都有一样的属性方法。

堆:存放对象实例,几乎所有的对象实例都在这里分配内存

存储的是new的俩个对象的 属性数据。(1,“admin”) (2,“admin”)

虚拟机栈:虚拟机栈描述的是Java方法执行的内存模型:每个方法被执行的时候都会同时创建一个栈帧(Stack Frame)用于存储局部变量表、操作栈、动态链接、方法出口等信息

存储的是对象地址,0x001 基本数据类型也存在栈中。

程序计数器:当前线程所执行的字节码的行号指示器,按照程序计数器,会指定执行顺序。指针操作。

本地方法栈:本地方法栈则是为虚拟机使用到的Native方法服务

本地方法接口:java运行时,线程sleep方法为典型的本地方法接口。

本地方法库:实现语言是c++写的,所有封装起来的方法都在本地方法库中。

2. 类加载器ClassLoader

负责加载class文件,class文件在文件开头有特定的文件标示,并且ClassLoader只负责class文件的加载,至于它是否可以运行,则由Execution Engine决定。
在这里插入图片描述
类加载器分为四种:前三种为虚拟机自带的加载器。

  • 启动类加载器(Bootstrap)C++

    负责加载$JAVA_HOME中jre/lib/rt.jar里所有的class,由C++实现,不是ClassLoader子类

  • 扩展类加载器(Extension)Java

    负责加载java平台中扩展功能的一些jar包,包括$JAVA_HOME中jre/lib/*.jar或-Djava.ext.dirs指定目录下的jar包

  • 应用程序类加载器(AppClassLoader)Java

    也叫系统类加载器,负责加载classpath中指定的jar包及目录中class

  • 用户自定义加载器 Java.lang.ClassLoader的子类,用户可以定制类的加载方式

工作过程:

  • 1、当AppClassLoader加载一个class时,它首先不会自己去尝试加载这个类,而是把类加载请求委派给父类加载器ExtClassLoader去完成。
  • 2、当ExtClassLoader加载一个class时,它首先也不会自己去尝试加载这个类,而是把类加载请求委派给BootStrapClassLoader去完成。
  • 3、如果BootStrapClassLoader加载失败(例如在$JAVA_HOME/jre/lib里未查找到该class),会使用ExtClassLoader来尝试加载;
  • 4、若ExtClassLoader也加载失败,则会使用AppClassLoader来加载
  • 5、如果AppClassLoader也加载失败,则会报出异常ClassNotFoundException

其实这就是所谓的双亲委派模型。简单来说:如果一个类加载器收到了类加载的请求,它首先不会自己去尝试加载这个类,而是把请求委托给父加载器去完成,依次向上
在这里插入图片描述
好处:防止内存中出现多份同样的字节码(安全性角度)
如果启动程序类,应用程序类都有一份字节码。可以保证在jvm运行时,只出现一次。
比如加载位于 rt.jar 包中的类 java.lang.Object,不管是哪个加载器加载这个类,最终都是委托给顶层的启动类加载器进行加载,这样就保证了使用不同的类加载器最终得到的都是同样一个 Object对象。

在此可以扩展一个问题:为什么不能直接从父类(BootStrap ClassLoader)往下查找?
可以在评论区进行回答

下面写段儿代码演示类加载器:

public class Demo {

    public Demo() {
        super();
    }

    public static void main(String[] args) {
        //  由启动类加载的:java.lang包
        Object obj = new Object();
        //  由启动类加载的:java.lang包
        String s = new String();
        //  自定义的加载器
        Demo demo = new Demo();
        //  获取到加载器: Bootstrap , 但是这个加载器实现 C++ 因此看到的是null
        System.out.println(obj.getClass().getClassLoader());
        //  获取到加载器: Bootstrap , 但是这个加载器实现 C++ 因此看到的是null
        System.out.println(s.getClass().getClassLoader());
        //  获取到加载器App ,Ext ,Bootstrap 但是这个加载器实现 C++ 因此看到的是null
        System.out.println(demo.getClass().getClassLoader().getParent().getParent());
        //  获取到加载器App的父级加载器:Ext ,并不是 由Ext 加载加载的
        System.out.println(demo.getClass().getClassLoader().getParent());
        //  获取到App 加载器!
        System.out.println(demo.getClass().getClassLoader());
    }
}

打印控制台中的sun.misc.Launcher,是一个java虚拟机的入口应用

3. 执行引擎Execution Engine

Execution Engine:执行引擎负责解释命令,提交操作系统执行。

4. 本地接口Native Interface

本地接口的作用是融合不同的编程语言为 Java 所用,它的初衷是融合 C/C++程序,Java 诞生的时候是 C/C++横行的时候,要想立足,必须有调用 C/C++程序,于是就在内存中专门开辟了一块区域处理标记为native的代码,它的具体做法是 Native Method Stack中登记 native方法,在Execution Engine 执行时加载native libraies。

​ 目前该方法使用的越来越少了,除非是与硬件有关的应用,比如通过Java程序驱动打印机或者Java系统管理生产设备,在企业级应用中已经比较少见。因为现在的异构领域间的通信很发达,比如可以使用 Socket通信,也可以使用Web Service等等,不多做介绍。

5. Native Method Stack

它的具体做法是Native Method Stack中登记native方法,在Execution Engine 执行时加载本地方法库。

6. PC寄存器

每个线程都有一个程序计数器,是线程私有的,就是一个指针,指向方法区中的方法字节码(用来存储指向下一条指令的地址,即 将要执行的指令代码),由执行引擎读取下一条指令,是一个非常小的内存空间,几乎可以忽略不记。

7. Method Area方法区 **

方法区是被所有线程共享,所有字段和方法字节码,以及一些特殊方法如构造函数,接口代码也在此定义。简单说,所有定义的方法的信息都保存在该区域,此区属于共享区间

静态变量+常量+类信息(构造方法/接口定义)+运行时常量池存在方法区中

But

实例变量存在堆内存中,和方法区无关

Stu stu = new Stu(1,“atguigu”,“bjcp”);

总结

以上就是今天要分享的内容,本文介绍了JVM的概述和体系结构,后续会详细讲解本篇文章中未提及的堆和栈。

如果觉得对你有帮助,可以动一动小手点赞关注。
在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值