Java基础之jvm1

发布于:2023-01-19 ⋅ 阅读:(548) ⋅ 点赞:(0)

一、概述

1. 概念

 java虚拟机,在实际的计算机上仿真模拟各种计算机功能。

2. 思维导图

在这里插入图片描述

3.jvm位置图

在这里插入图片描述

4. jvm体系结构

4.1 简图

高效记忆:JVM架构简图

(1)头发:头上的假发(.java File)被发卡(.class File)卡得非常热(class loader
(2)眼睛:眼睛看到很多深圳本地(**本地方法栈)**人站()在大街上,人多的计数器(计数器)都算不过来,原来周杰伦来开演唱会了!
(3)耳朵:耳朵没有办法(方法区)听到外面的声音,因为房子是全部用隔音墙堆()的。
(4)鼻子:我的鼻子直接(直接内存)闻到了很远(元数据区)的红烧牛肉的味道,太香了!
(5)嘴巴:我用本地方法(本地方法库)吃东莞烧鹅,然后直接口(本地方法接口)吃了,最后无法执行(执行引擎)今天的演讲任务了。

在这里插入图片描述

4.2 详细图

在这里插入图片描述

5.ClassLoader(类加载器)

5.1 类加载

5.1.1 概念

(1)Java File 文件经过编译后变成 .class File字节码文件
(2)class File字节码文件通过类加载器加载到 JVM 虚拟机中。

5.1.2 运行时数据区

虚拟机主要的 5 大块:
(1)栈和本地方法栈和计数器都是独享区域,不存在线程安全问题。
(2)方法区,堆都为线程共享区域,有线程安全问题。
(3)JVM 的调优主要围绕栈、堆两大块进行。
在这里插入图片描述

5.2 类加载

5.2.1流程图

高效记忆 :类加载流程

(1)今天我太无聊了,于是下载(加载)了抖音安装包,安装抖音的时候,手机会先验证(验证)安装包的安全性。
(2)安装好后抖音会做好自启动、开启定位等准备(准备),然后会解析(解析)我的用户名和密码等信息,最后初始化(初始化)信息。
(3)当我使用(使用)一天后觉得浪费了太多时间,于是又把抖音卸载(卸载)了。

上述可以结合自己对具体过程联合记忆,如:

加载:加了2个擂(2进制类)台,擂台上东西堆成了卡车模特队形象。(class对象)
验证:验证文件格式中是否有字节码、引用符号
准备:准备嫁给变态(静态变量)却被默认(初始默认值)了
解析:引用符号直接引用
初始化:变态被赋予正确的初始价值

在这里插入图片描述

5.2.2 顺序

(1)加载、验证、准备和初始化这4个阶段发生的顺序是确定的,而解析阶段则不一定。
(2)解析可以在初始化之后开始,是为了支持 Java 语言的运行时绑定
(3)另外这5个阶段是按顺序开始,而不是按顺序进行或完成。
(4)这些阶段通常都是互相交叉地混合进行,通常在一个阶段执行的过程中调用或激活另一个阶段。

5.2.3 概述

(1)加载:查找并加载类的二进制数据,在 Java 堆中创建一个 java.lang.Class 类的对象;

(2)连接:连接包含:验证、准备、初始化;

  • 验证:文件格式、元数据、字节码、符号引用验证;
  • 准备:为类的静态变量分配内存,并将其初始化为默认值;
  • 解析:把类中的符号引用转换为直接引用。

(3)初始化:为类的静态变量赋予正确的初始值;

  • BootStrap ClassLoader:rt.jar
  • Extention ClassLoader:加载扩展的 jar 包
  • App ClassLoader:指定的 classpath 下面的 jar包
  • Custom ClassLoader:自定义的类加载器

(4)使用:new出对象程序中使用;

(5)卸载:执行垃圾回收。

5.3 类加载器

高效记忆:类加载分类

我引导(引导类加载器)爸妈扩展了 (扩展类加载器)微信聊天应用(应用类加载器)的用户自定义表情(用户自定义类加载器)。

5.3.1 启动/引导类加载器

Bootstrap

(1)主要加载的是JVM自身需要的类,使用C++语言实现,
(2)负责将 <JAVA_HOME>/lib路径下的核心类库或-Xbootclasspath参数指定的路径下的jar包加载到内存中
,只加载包名为java、javax、sun等开头的类。

5.3.2 扩展类加载器

Extension
(1)加载系统类路径java -classpath或-D java.class.path 指定路径下的类库,开发者可以直接使用
(2)一般情况下该类加载是程序中默认的类加载器,通过ClassLoader#getSystemClassLoader()方法可以获取到该类加载器。

5.3.3 系统/应用类加载器

System、Application

5.3.4 用户自定义加载器

 **Custom **

5.4 类加载实例

5.4.1 图

在这里插入图片描述

5.4.2 获取类加载器的代码

class Person{
}


public class TestClassLoader {
    public static void main(String[] args) {

        Person person_01 = new Person();
        Person person_02 = new Person();
        Person person_03 = new Person();

        //发现person_01,person_02,person_03的hashCode一致,代表这三个实例化对象隶属于一个Class,即Person
        System.out.println(person_01.hashCode());
        System.out.println(person_02.hashCode());
        System.out.println(person_03.hashCode());

        //Person实例化对象person_01通过getClass()方法得到Class对象Person
        Class Person = person_01.getClass();
        //Person通过getClassLoader()方法得到系统类加载器
        ClassLoader myClassLoader = Person.getClassLoader();
        System.out.println(myClassLoader.hashCode());
        //加载器对象myClassLoader通过getParent()方法得到拓展类加载器
        ClassLoader myParentClassLoader = myClassLoader.getParent();
        System.out.println(myParentClassLoader.hashCode());
        //加载器对象myGPClassLoader通过getParent()方法得到引导类加载器
        ClassLoader myGPClassLoader = myParentClassLoader.getParent();
        System.out.println(myGPClassLoader.hashCode()); //发现报错,无法通过方法获取引导类加载器
    }

}

6.双亲委派机制

6.1 类加载器间关系图

在这里插入图片描述
备注
 父类加载器并非通常所说的类继承关系,而是采用组合关系来复用父类加载器的相关代码。

6.2 工作原理

高效记忆:双亲委派原理

(1)子类(类加载器)班级学生会收到校外联谊请求(类加载请求)访问后,不是自己班级学生会先去决定并执行(加载执行)接待,而是先委托给父类(父类加载器)系级学生会去决定接待,
(2)如果父类(父类加载器)系级学生会还有父类(父类加载器)院级学生会,则进一步向上委托,直到顶级父类(顶级类加载器)总学生会。
(3)父类(父类加载器)总学生会决定接待后,如果需要父类(父类加载器)总学生会执行接待,就由父类(父类加载器)总学生会直接执行接待
(4)如果父类(父类加载器)总学生会不需要亲自执行接待,则让他子类(子类加载器)院级学生会去执行接待。

(1)一个类加载器收到类加载请求后并不会自己先去加载,而是把请求委托给父类的加载器去执行
(2)如果父类加载器还存在其父类加载器,则进一步向上委托直到顶级类加载器,
(3)如果父类加载器完成类加载,就成功返回
(4)如果父类加载器未完成类加载,其子类加载器就会去加载。

6.3 优点

(1)确保类只被加载一次, 避免重复加载
(2)用户即使自定义同样路径的java.lang.Integer类,最后加载还是jdk的Integer类。
避免了恶意篡改核心包的风险。

7.沙箱安全机制

7.1 概念

(1)将 Java 代码限定在虚拟机特定的运行范围中,并且严格限制代码对本地系统资源访问。
(2)保证对代码的有效隔离,防止对本地系统造成破坏。
(3)沙箱主要限制CPU、内存、文件系统、网络等系统资源访问。

7.2 沙箱的基本组件

7.2.1 字节码校验器(bytecode verifier)

(1)确保Java类文件遵循Java语言规范,帮助Java程序实现内存保护
(2)核心类等不用经过字节码校验

7.2.2 类加载(class loader)

(1)防止恶意代码去干涉善意的代码;
(2)守护了被信任的类库边界;
(3)将代码归入保护域,确定了代码可以进行哪些操作。

二、jvm详解

运行时数据区域

(1)Java 程序在运行时,会为 JVM 单独划出一块内存区域。
(2)这块内存区域又可以再次划分出一块运行时数据区,含以下五个部分:
在这里插入图片描述

高效记忆:JVM运行区数据类型

(1)我在客栈(栈)里的8(8大基本数据类型)个对象饮用(对象引用)青梅煮酒,
(2)因为不讲究喝酒方法(方法区)醉的一塌糊涂,最后都变态(静态变量)地躺在敞亮水池(常量、运行时常量池)中,累的没有办法起来(类、方法),
(3)等我醒来发现,前面都是我堆(堆)集的梦里new出来的对象(new的对象实例)

1.本地方法栈(Native)

Native Method Stack

1.1 本地方法

(1)凡是带了native关键字的,说明java的作用范围达不到了,回去调用底层c语言的库!
(2)会进入本地方法栈,然后去调用本地方法接口将native方法引入执行

1.2 本地方法栈

(1)线程独享区,负责登记native方法
(2)在执行引擎( Execution Engine )执行的时候,通过本地方法接口(JNI)加载本地方法库中的方法。
(3)如果线程请求的栈深度大于虚拟机所允许的深度,将抛出 StackOverflowError 异常;
(4)如果虚拟机栈可以动态扩展,当扩展时无法申请到足够的内存时会抛出 OutOfMemoryError异常。

2.虚拟机栈:简称栈

2.1 概述

(1)线程私有,每个线程独享一个虚拟机栈,生命周期与线程相同。
(2)描述Java 方法执行的内存模型:

  • 每个方法被执行的时候都会同时创建一个栈帧(Stack Frame)
  • 栈帧用于存储局部变量表、操作栈、动态链接、方法出口等信息。
  • 每一个方法被调用直至执行完成的过程,就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。
    (3)栈内存主管程序的运行、生命周期和线程同步。线程结束,栈内存就释放,不存在垃圾回收问题。
    (4)栈内存中运行:8大基本类型+对象引用.
    (5)与本地方法栈一样,虚拟机栈区域也会抛出 StackOverflowError 和 OutOfMemoryError 异常。

2.2 栈图

在这里插入图片描述

2.3 栈流程

2.3.1 流程概述

例:int a=7

(1)局部变量表:存放局部变量(a)

(2)操作数栈:存放操作数(7)

(3)动态链接:将符号引用转成直接引用(符号引用就是你知道调用了谁,直接引用就是你拿到将要要调用的方法的地址)

(4)方法出口:方法结束

2.3.2 流程图

在这里插入图片描述

3.PC程序计数器

(1)线程私有,每个线程都有一个。
(2)记录当前线程所执行的位置。
(3)当线程获得 CPU 的执行权的时候,就直接从记录的位置开始执行。
分支、循环、跳转、异常处理也都依赖这个程序计数器来完成。

4.方法区(Method Area)

(1)所有线程共享区域,线程不安全区域。
(2)存储已被虚拟机加载的类、方法信息等,如类信息(构造方法、接口定义)(Class)、静态变量(static)、常量(final)、运行时常量池、即时编译器编译后的代码等数据。但是实例变量存在堆内存中
(3)无法满足内存分配需求时,将抛出 OutOfMemoryError 异常。

5.堆

5.1 概述

(1)线程共享区域,因此是线程不安全的。
(2)一个JVM只有一个堆内存,堆内存的大小是可以调节的
(3)存储的是我们 new 来的对象即对象实例,不存放基本类型和对象引用。
(4)类加载器读取类文件后,一般会把类、方法、常量、变量及所有引用类型的真实对象放入堆中。
(5)由于创建了大量的对象,垃圾回收器主要工作在这块区域;
(6)会发生 OutOfMemoryError

5.2 结构图

在这里插入图片描述
在这里插入图片描述

5.3 新生区

5.3.1 概念

类的诞生,成长和死亡的地方

5.3.2 组成

(1)伊甸园区:所有对象都在伊甸园区new出来
(2)幸存0区和幸存1区:轻GC之后存下来的

5.4 老年区(养老区)

多次轻GC存活下来的对象放在老年区

8.5 永久区

jdk1.8后称为元空间:逻辑上存在,物理上不存在 ,因为:存储在本地磁盘内,不占用虚拟机内存
在这里插入图片描述
在这里插入图片描述

9.总结

(1)栈:基本类型的变量,对象的引用变量,实例对象的方法
(2)堆:存放由new创建的对象
(3)方法区:Class对象,static变量,常量池(常量)

备注: 默认情况下,JVM使用的最大内存为电脑总内存的四分之一,JVM使用的初始化内存为电脑总内存的六十四分之一.


一篇跳转—Java基础之jvm2


参考链接1

参考链接2


随心所往,看见未来。Follow your heart,see night!

*欢迎点赞、关注、留言,收藏及转发,一起学习、交流!

本文含有隐藏内容,请 开通VIP 后查看