2023.9.1 简单认识 JVM

news/2024/6/16 22:05:27 标签: jvm, java

目录

JVM 内存划分

本地方法栈

虚拟机栈

程序计数器

堆区

元数据区

JVM 类加载机制

加载

验证

准备

解析

初始化

类被加载的几种情况(懒汉模式 ---> 只要被用到才会被加载)

双亲委派模型


JVM 内存划分

  • JVM 是一个应用程序,在它启动的时,需要从操作系统中申请内存一部分内存区域!
  • 每个 JVM 就是一个 Java 进程

划分图:


本地方法栈

  • 本地则表示 JVM 内部的 C++ 代码,就是给调用本地方法(JVM 内部的方法)所准备的栈空间

虚拟机栈

  • 给 Java 代码使用的栈空间,用来存储局部变量、方法参数、返回值 等
注意:
  • 此处的栈跟数据结构中的栈不是同一个东西
  • 数据结构的栈是一个通用的,更广泛的概念,此处的栈特指 JVM 中的一个特定空间
  • 本地方法栈 存储本地方法之间的调用关系
  • 虚拟机栈 存储方法之间的调用关系
  • 整个栈空间包含多个栈帧,每个栈帧表示一个方法,其中包含方法的入口地址、参数、返回地址、局部变量等
  • 每个线程都有自己独立的栈

程序计数器

  • 存储当前线程执行的字节码指令地址,记录当前线程执行到哪个指令,每个线程都有自己独立的程序计数器

堆区

  • 堆是 JVM 中最大的一块内存区域,用于存储对象实例和数组,一个进程只有一份,被所有线程共享,通过垃圾回收来管理内存的分配与释放

元数据区

  • 用来存储类的信息、常量、静态变量、静态成员 等 

总结:

  • 局部变量在栈上
  • 普通成员变量在堆上
  • 静态成员变量在元数据区上

JVM 类加载机制

  • 指将类的字节码(.class文件)加载到内存中(元数据区),并在运行时将其转换为可执行的 Java 类

机制图:


加载

  • 通过类加载器,根据类的名字查找相对应的字节码文件,把类的字节码数据(.class文件)加载到 JVM 中并转化为其内部的数据结构

验证

  • 验证阶段 JVM 检查字节码的格式、语义、安全性等方面的问题,以确保被加载的字节码符合 JVM 规范的过程

准备

  • 准备阶段 JVM 为类的静态变量(static修饰的变量)分配内存空间,并根据其类型设置如 0 、false、null 这样的默认初始值


解析

  • 解析阶段是将常量池中的 符号引用(类、方法、字段等符号) 替换为 直接引用(指向实际内存地址的指针) 的过程,也就是初始化常量的过程

初始化

  • 初始化阶段是执行类的初始化代码的过程,JVM 会按照代码顺序执行类的静态初始化块和静态变量的赋值操作

类被加载的几种情况(懒汉模式 ---> 只要被用到才会被加载)

  • 构造类的实例
  • 调用这个类的静态方法、使用这个类的静态属性
  • 加载子类,便会加载其父类
  • 该类一旦被加载过,后续再使用便不会重复加载

双亲委派模型

  • 属于 Java 类加载机制中的一种设计模式,描述的是加载阶段,寻找 .class 文件的基本过程
  • 默认提供了三个类加载器
Bootdtrsp Class LoaderExtension Class LoaderApplication Class Loader
加载标准库中的类加载 JVM 拓展库中的类加载用户提供的第三方库、用户项目代码 中的类
  • 上述三个类加载器存在父子关系 ,子 类加载器上有一个 parent 属性指向其父 类加载器

具体类加载过程:

  • 当一个类加载器收到加载类的请求时,它首先检查是否已经加载过这个类。如果已经加载过,则直接返回该类的 Class 对象

  • 如果类没有被加载过,那么该类加载器会将加载任务委派给父加载器去完成

  • 父加载器会按照相同的规则进行加载,即首先检查是否已经加载过该类,如果加载过则返回 Class对象,否则继续委派给它的父加载器

  • 这个过程一直往上委派,直到达到顶层的启动类加载器(Bootdtrsp Class Loader)。启动类加载器是 JVM 的一部分,它负责加载 Java 的标准库

  • 如果顶层的启动类加载器无法加载类,那么其子加载器会尝试自己加载类,它会通过自己的类路径搜索字节码文件,并将字节码转换为 Class 对象

例图:(加载 java.lang 类)

  • 这个加载顺序的主要目的是为了让 Bootdtrsp Class Loader 启动类能够先加载,Application Class Loader 启动类后加载。因为这样可以避免用户创建一些奇怪的类,引起不必要的 bug(用户自己写的类与标准库中的类重名)

双亲委派模型的优点:

  • 避免重复加载:每个类加载器都会缓存已加载的类,避免了同一个类被多次加载的情况

  • 安全性:通过双亲委派模型,核心类库由启动类加载器加载,这样可以保证核心类库的安全性,防止恶意代码替换核心类

  • 一致性:相同的类在不同的类加载器中只会存在一个实例,保证了类的一致性

  • 可扩展性:开发者可以通过自定义类加载器并继承现有的加载器,实现特定的类加载行为,从而实现动态的类加载和扩展


http://www.niftyadmin.cn/n/4992669.html

相关文章

Spring-TX 事务

目录 一、事务的种类 二、Spring事务管理器 三、事务注解使用 四、事务注解属性 一、事务的种类 1.编程式事务 所谓编程式事务就是用代码手写事务,包含了事务的开始,具体事务,事务的提交和事务的回滚。在这期间就会产生一些冗余问题&am…

Anaconda虚拟环境下导入opencv

文章目录 解决方法测试 解决方法 1、根据自己虚拟环境对于的python版本与电脑对应的位长选择具体的版本,例如python3.9选择cp39,64位电脑选择64 下载地址:资源地址 若是不确定自己虚拟环境对应的python版本,可以输入下列命令&…

Jetpack业务架构—四件套(Lifecycle、ViewModel、LiveData、DataBinding)

Jetpack 是一个由多个库组成的套件,可帮助开发者遵循最佳做法、减少样板代码并编写可在各种 Android 版本和设备中一致运行的代码,让开发者可将精力集中于真正重要的编码工作。 Android Jetpack组件的优势: Jetpack推出的主要目的是为了能够…

Tomca架构细节

一.整体架构 1.1 从请求的处理过程看总体架构 如上图中的图 1 和图 2: 在图 1 中,HTTP 服务器直接调用具体的业务类,各个应用程序和服务器是紧耦合的。 这种架构下,HTTP 需要接受不同的请求,并根据不同的请求调用不…

编程题四大算法思想(三)——贪心法:找零问题、背包问题、任务调度问题

文章目录 贪心法找零问题(change-making problem)贪心算法要求基本思想适合求解问题的特征 背包问题0/1背包问题0/1背包问题——贪心法 分数背包问题 任务调度问题 贪心法 我在当前情况下,我把我做到最好。我也不管全局如何,整体如…

Oracle表索引查看方法总结(查看oracle表索引)

Oracle表索引查看方法总结 Oracle是当前应用最广泛的关系数据库,也是多数大型企业使用的数据库。Oracle表索引在提高查询效率方面起着至关重要的作用,掌握该方法也是技术人员必备技能之一。本文总结了几种常见的查看Oracle表索引信息的方法,…

目标检测YOLO算法,先从yolov1开始

学习资源 有一套配套的学习资料,才能让我们的学习事半功倍。 yolov1论文原址:You Only Look Once: Unified, Real-Time Object Detection 代码地址:darknet: Convolutional Neural Networks (github.com) 深度学习经典检测方法 one-stag…

lightdb 支持兼容Oracle的to_clob函数

文章目录 概述案例演示 概述 在信创移植的SQL语句中,有来源于Oracle数据库的SQL语句。 在ORACLE PL/SQL包中,你可以使用TO_CLOB(character)函数将RAW、CHAR、VARCHAR、VARCHAR2、NCHAR、NVARCHAR2、CLOB值转换为CLOB。 因此在LightDB 23.3版本中实现了…