2023.9.1 简单认识 JVM

目录

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.hqwc.cn/news/93733.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

万级数据优化EasyExcel+mybatis流式查询导出封装

文章目录 前言.万级数据优化一. 直接上流式查询封装工具代码二. 传统分页导出查询三. 流式查询概念游标查询 前言.万级数据优化 我们不妨先给大家讲一个概念,利用此概念我们正好给大家介绍一个数据库优化的小技巧: 需求如下:将一个地市表的数…

创建型模式-建造者模式

使用多个简单的对象一步一步构建成一个复杂的对象 主要解决:主要解决在软件系统中,有时候面临着"一个复杂对象"的创建工作,其通常由各个部分的子对象用一定的算法构成;由于需求的变化,这个复杂对象的各个部…

Linux内核源码分析 (5)多处理器调度

Linux内核源码分析 (5)多处理器调度 文章目录 Linux内核源码分析 (5)多处理器调度注:本章节使用的内核版本为Linux 5.6.18一、 SMT和NUMA1、SMP (对称多处理器结构)2、NUMA (非一致内存访问结构) 二、多核调度三、调度域和调度组四、SMP调度详…

为了更好和大家交流,欢迎大家加我的微信账户

因为一些懂的都懂的原因,如果我的账户显示为 此时我无法通过站内信、留言或者任何方式和大家联系。 如果看到这样的内容,可以在此评论区留下你的微信账户,我看到后会添加你。为防止其他人冒充我,我的微信号以2206结尾。

Docker harbor 私有仓库的部署和管理

目录 一、什么是Harbor 二、Harbor的特性 三、Harbor的构成 四、部署配置Docker Harbor 1. 首先需要安装 Docker-Compose 服务 2.部署 Harbor 服务 3.使用harbor仓库 (1)项目管理 (2)用户管理 一、什么是Harbor Harbor …

【IOTE】物联网射频模组和芯片级方案提供商——深圳信驰达科技将精彩亮相IOTE物联网展

►►►强势来袭 Strong Attack 主物联场,相约深圳;2023,共论商机!IOTE2023第二十届国际物联网展深圳站将于2023年9月20-22日在深圳国际会展中心(宝安新馆)开展!汇聚全球超800家参展企业,呈现更多数字化纷呈…

从零开发JavaWeb入门项目--十天掌握

原文网址:从零开发JavaWeb入门项目--十天掌握_IT利刃出鞘的博客-CSDN博客 简介 这是一个靠谱的JavaWeb入门项目实战,名字叫蚂蚁爱购。从零开发项目,视频加文档,十天就能学会开发JavaWeb项目,教程路线是:搭…

uni-app中使用iconfont彩色图标

uni-app中使用iconfont彩色图标 大家好,今天我们来学习一下uni-app中使用iconfont彩色图标,好好看,好好学,超详细的 第一步 首先,从iconfont官网(iconfont-阿里巴巴矢量图标库)选择自己需要的图…

Leetcode110. 平衡二叉树

力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台 给定一个二叉树,判断它是否是高度平衡的二叉树。 本题中,一棵高度平衡二叉树定义为: 一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1 。 题解&#xff…

Linux测开常用命令总结

文章目录 Linux系统中文件目录树 基本指令的使用: Linux命令的帮助信息查看 --help command --help 说明: 显示command 命令的帮助信息通过man命令查看帮助信息 man command( 命令的名称) man 命令查看的帮助信息更加详细ls,pwd&#xff0c…

原生js实现轮播图及无缝滚动

我这里主要说轮播图和无缝滚动的实现思路,就采用最简单的轮播图了,当然实现的思路有很多种,我这也只是其中一种。 简单轮播图的大概结构是这样的,中间是图片,二边是箭头可以用来切换图片,下面的小圆点也可以…

代码随想录笔记--栈与队列篇

目录 1--用栈实现队列 2--用队列实现栈 3--有效的括号 4--删除字符串中的所有相邻重复项 5--逆波兰表达式求值 6--滑动窗口的最大值 7--前k个高频元素 1--用栈实现队列 利用两个栈&#xff0c;一个是输入栈&#xff0c;另一个是输出栈&#xff1b; #include <iostrea…