学习笔记4——JVM运行时数据区梳理

news2024/11/24 11:26:17

学习笔记系列开头惯例发布一些寻亲消息

链接:https://baobeihuijia.com/bbhj/contents/3/192489.html
在这里插入图片描述


类装载器classLoader:

  • 将本地的字节码文件.class 加载到内存方法区中成为元数据模板(两个class对象是否为同一个类要求:完整类名包括包名一致+加载类的classloader要一致)

    • 启动类加载器,用于提供JVM自身需要的类(除了启动类加载器,其他都继承自classloader)

    • 扩展类加载器:从用户指定目录中加载类

    • 应用程序类加载器:加载环境变量/系统属性指定路径下的类库,是程序中默认的类加载器

    • 用户自定义类加载器

双亲委派机制:

  • 按需加载,需要用到该类的时候才会加载到内存中生成class对象
  • 向上委托,父类加载失败则由子加载器处理
  • 优点:
    • 避免类重复加载
    • 防止核心api被随意更改【沙箱安全】:自定义string类,在加载的自定义string类的时候会率先使用引导类加载器加载jdk自带的string.class文件,可以保证对java核心源代码的保护

在这里插入图片描述

在这里插入图片描述

运行时数据区:

  • JAVA内存布局规定了java运行过程中内存申请,分配和管理的策略:

    • 每个线程独立拥有程序计数器、栈、本地方法栈

    • 线程共享,随虚拟机存亡的:方法区、堆

程序计数器

  • (由于cpu一直在线程中切换,利用程序计数器可以记住切回来后继续执行的位置【cpu时间片:cpu分给各个线程的时间段】)

    • pc寄存器用来存储指向下一条指令的地址/如果该线程执行的是native方法,则是未指定值

    • 通过pc来控制程序的分支、循环、跳转等

    • 字节码解释器就是通过pc来找到下一条即将要执行的字节码指令

    • 是jvm中唯一一个没有规定任何outofmemoryerror情况的

虚拟机栈(栈帧就类似于寄存器之间的倒换)

  • java的指令都是基于栈来设计的,因为不同的平台cpu架构不同,所以不能设计基于寄存器的
  • 随着方法的执行,java栈的操作就是对栈帧的入栈还有出栈,不存在垃圾回收问题(之前的基于寄存器的方法执行是通过寄存器来转移操作数据)
  • 栈可能出现的异常
    • 线程请求分配的栈容量超过java的栈最大容量,就抛出stackoverflowerror异常
    • 如果是没有内存来创建或者满足栈要求,就抛出outofmemoryerror异常
  • 每个线程都有自己的栈,栈中数据是以栈帧格式存在的,执行引擎运行所有的字节码指令只针对当前栈帧进行,也就是说一个时间点只会有一个活动的栈帧,如果该方法调用了别的方法,那么别的方法的栈帧就会被创建并放到栈顶端,成为当前栈帧
  • 栈帧中包括:
    • 局部变量表
      • 局部变量表所需的大小在编译的时候就写在了字节码文件中,所以大小是固定的
      • 以slot为基本存储单位
      • 当一个方法被执行引擎调用的时候,该方法的方法参数和内部定义的局部变量都会按照执行顺序被复制到局部变量表中的slot上
      • 局部变量表必须进行人为的初始化,没有系统自带的准备阶段初始为0,没有赋值就不能使用
    • 操作数栈
      • 保存计算过程的中间结果,同时是计算过程中变量的临时存储空间
      • 并非使用索引来进行数据访问,而是通过数据的出栈和入栈来完成一次访问
      • 栈顶缓存技术:将频繁的栈顶读写缓存到物理cpu中,降低对内存的读写
    • 动态链接(指向运行时常量池的方法引用,将符号转化为调用方法的直接引用)
      • 静态链接(早期绑定):在编译期可知,且运行期不变,用静态链接直接替换
      • 动态链接(晚期绑定):编译期无法确定,要根据程序运行时的实际类型才能确定【比如我们是通过一个变量值>3来判断执行哪个方法,像这样就无法直接替换,就需要在运行时进行动态的链接/支持多态】
        • 虚方法表:每次动态分派的过程都要在类的方法元数据中找到合适的目标,因此在类的方法区建立虚方法表使用索引来代替查找
    • 方法返回地址
      • 存放调用该方法的pc寄存器的值,即调用该方法的下一条指令的地址
      • 若是异常退出,则返回地址是要通过异常表来确定

在这里插入图片描述

Java方法内的局部变量是否线程安全问题_在方法中会产生线程安全问题吗对吗-CSDN博客

本地方法栈

  • 调用本地的一些基于C编写的程序时,采用本地方法栈来管理本地方法的调用

  • 当某个线程调用一个本地方法时,它就进入了一个全新的并且不再受虚拟机限制的世界。它和虚拟机拥有同样的权限。

  • 是JVM中分配内存最大的一块区域,如果内存大小超过-Xmx指定的最大内存就会抛出outofmemeryerror

    • 为什么xms和xmx要设置成相同的值?【精选】jvm调优技巧 - 内存抖动 、Xms和Xmx参数为什么要设置相同的值_xmx和xms为什么要一样-CSDN博客

      xms是发现空余堆内存大于阈值,jvm减小直到xms最小

      xmx是发现空余堆内存小于阈值,jvm增大直到xmx最大

      1、首先,如果-Xms起初值设置的比较小,那么就频繁触发GC操作。当GC操作无法释放更多内存时,会进行内存的扩充。

      2、内存扩充的时候,会出现内存抖动的情况

      【就比如我上街看到一个很喜欢的商品,想要买下这个商品,但是我身上的钱不够了, 于是我向你借钱,你同意了,然后你掏出钱包, 把钱拿出来,然后再交给我,你拿钱给我的这整个过程也是需要时间的。所以我为了省下这个拿钱的时间,我在一开始出门的时候就直接带上足够的钱,这样就可以省下借钱的时间了】

  • 为对象分配内存TLAB

    • 为避免多个线程操作同一堆区的对象地址,使用TLAB机制,如果失败那就使用加锁机制确保数据操作的原子性
  • 对象不一定全部分配在堆上,采用逃逸分析时,即对象只在方法体内使用时,也可以分配到栈中
    在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

方法区

  • 实际物理内存空间和堆一样可以不连续的,如果方法区定义了太多的类,那么方法区也会outpfmemoryerror
  • 在这个类加载阶段包括两部分,一是对静态变量的加载(分为static和final static),二是对类的加载
  • 内部结构
    • 类型信息:全名(包名.类名),直接父类的完整有效名,修饰符,直接接口
    • 域信息
    • 方法信息:方法名,方法返回类型,参数,修饰符,字节码,操作数栈,局部变量表以及大小,异常表
  • 方法区是运行时常量池、字节码文件内部包含常量池
    在这里插入图片描述

常量池(字节码)和运行时常量池(方法区)

  • 一个java源文件中的类、接口,编译后产生一个字节码文件。而Java中的字节码需要数据支持,通常这种数据会很大以至于不能直接存到字节码里,换另一种方式,可以存到常量池,这个字节码包含了指向常量池的引用。

  • 这部分内容在类加载后存放到方法区的运行时常量池中,其中每个已加载的类都会维护一个常量池,通过索引访问

    • 编译期就明确数值字面量
    • 运行期才能获得方法或者字段引用,此时就不再是常量池中的符号地址了,而是真实地址

大概梳理流程:

【创建轮子,车架】我将我的java文件打包生成字节码文件,当我点击运行的时候,启动类会被主动加载,jvm的类加载器就会

  • 加载类中的静态变量到方法区,直接分配内存(可能分配到永久代/堆)
  • 加载字节码中的类信息到方法区(按需加载,需要用到该类的时候才会加载到内存),包括类名,域名,方法名,并且将类的常量池放到方法区的运行时常量池中(根据这个信息才能将类完整的刻画出来),将符号引用变为直接的内存地址

【实例化四个轮子,车架】jvm开启线程,主动对启动类进行类的初始化:先进行类初始化,即将方法区/堆区的静态变量进行初始化,执行静态代码块,然后是对象初始化,new的对象放到jvm的堆中,执行赋值语句,普通代码块,最后是构造函数代码。

【组装】jvm在栈中开启一个栈帧记录线程,在运行时加载该方法的局部变量表,利用操作栈对数据进行循环,遍历运算,如果在执行过程中遇到了对象引用,那就去方法区的运行时常量池将符号转化为直接引用,执行完毕后,堆中的对象被清除。

在这里插入图片描述

面试题

在这里插入图片描述

在这里插入图片描述

当在多次minor GC后仍然存活的满足一定存活代数的对象,或者是由于太大无法在新生代中分配的对象

在这里插入图片描述

java8之前,两种模式

  • 所有的类信息(运行时常量池)和静态变量,字符串常量都放在永久代上
  • 只剩类信息(运行时常量池)在永久代 / 静态变量,字符串常量放在堆中

java8之后

  • jvm没有永久代的概念,类信息(运行时常量池)放在本地内存上,叫元空间

为什么有这个变动呢?

  • 因为随着类加载变多,我们无法定义一个合适的永久代空间,因此放到本地的话,元空间的大小只受限于本地的内存大小
  • 原始字符串常量放在永久代中,只有full GC(老年代或者永久代不足)的时候才会被清理,回收效率不高,所以新的改进是放到堆中,跟随对象及时回收内存

行时常量池)放在本地内存上,叫元空间

为什么有这个变动呢?

  • 因为随着类加载变多,我们无法定义一个合适的永久代空间,因此放到本地的话,元空间的大小只受限于本地的内存大小
  • 原始字符串常量放在永久代中,只有full GC(老年代或者永久代不足)的时候才会被清理,回收效率不高,所以新的改进是放到堆中,跟随对象及时回收内存

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1183463.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

对话句子互动创始人李佳芮 | AIGC结合私域运营影响不可估量

“ 创业最核心的就是耐心” 口述 | 李佳芮 整理 | 小白&云舒 出品|极新 极新请文心一言分析了私域流量运营和chatbot当下的发展背景,它给出了以下答案: 1. 移动设备普及和网络速度提升:随着智能手机和移动互联网的普及&…

UE5.3实现1秒12帧风格的动画抽帧效果

现今一些卡通风格游戏会刻意模仿早期动画1秒12帧的播放效果,以营造较强的风格化体验,博主在UE5中实现了一下(左侧正常动画,右侧抽帧动画): 我们可以通过在UE中对导入设置进行一些修改,达到不改…

Android UI 开发·界面布局开发·案例分析

目录 ​编辑 1. 线性布局(LinearLayout) 2. 相对布局(RelativeLayout) 3. 表格布局(TableLayout) 4. 帧布局(FrameLayout) 5. 网格布局(GridLayout&#xff0…

AI:68-基于深度学习的身份证号码识别

🚀 本文选自专栏:AI领域专栏 从基础到实践,深入了解算法、案例和最新趋势。无论你是初学者还是经验丰富的数据科学家,通过案例和项目实践,掌握核心概念和实用技能。每篇案例都包含代码实例,详细讲解供大家学习。 📌📌📌在这个漫长的过程,中途遇到了不少问题,但是…

C语言编写一个程序采集招聘信息

因为在这里无法详细解释每行代码和步骤。但是,我可以给大家一个使用Python和requests库编写的简单爬虫程序的例子,它可以从网站上获取招聘信息。你可以根据这个例子,将其改写为使用C语言编写的爬虫程序。 import requests# 指定爬虫IP信息 pr…

二叉树的OJ题——C++

一、根据二叉树创建字符串 题目链接: 606. 根据二叉树创建字符串 - 力扣(LeetCode) 题目描述: 前序遍历二叉树,并且将结果存入到一个string中,并且要使用括号去分割和表示每个节点和子树之间的关系&…

大漠插件(二、Qt使用插件时注意事项)

本章目的 在上篇已经注册完毕大漠,那么怎么使用大漠来制作脚本,我选择了我最熟悉的Qt来开发,毕竟只是小软件,用脚本或者c都差不了多少。本章就是开发途中的一些坑。 本人开发环境是 win11 64、Qt 5.15.2安装了5.10.0的msvc2015 32…

接口测试工具的实验,Postman、Swagger、knife4j(黑马头条)

一、Postman 最常用的接口测试软件,需要注意点:在进行post请求时,需要选择JSON形式发送 输入JSON字符串,比如: {"maxBehotTime": "2021-04-19 00:19:09","minBehotTime": "2021-…

支持存档的书签服务LinkWarden

什么是 LinkWarden ? Linkwarden 是一个自托管、开源协作书签管理器,用于收集、组织和存档网页。目标是将您在网络上找到的有用网页和文章组织到一个地方,并且由于有用的网页可能会消失(参见链接失效的必然性)&#xf…

读者自荐的 4 个 GitHub 项目

本期推荐的 4 个开源项目,为读者在开源项目 Awesome-GitHub-Repo 的评论区自推的, 如果你开源了不错的项目,想让大家看到,也可以去 Awesome-GitHub-Repo 进行投稿。 本期推荐开源项目目录: 1. DB-GPT 2. 定制中国传统节日头像 3. …

闪客网盘系统源码,已测试对接腾讯COS及本地和支付(支持限速+按时收费+文件分享+可对接易支付)- 修复版

正文概述 资源入口 支持对文件下载限速 对接易支付 推广赚钱啥的功能 源码非常的好 支持腾讯cos 阿里云cos 本地储存 远程存储 源码仅支持服务器搭建 php7.2 伪静态thinkphp 运行目录public 导入数据库 修改config目录下的database.php数据库信息 后台地址: 域名/ad…

参考文献管理软件 EndNote 21 mac v21.2中文版特点和功能

EndNoter mac是一款参考文献管理软件,旨在帮助学术研究者、学生和专业人士有效地管理和引用参考文献。该软件提供了许多功能,使用户可以轻松地组织、搜索和引用各种类型的文献。 EndNoter mac软件特点和功能 1. 参考文献管理:EndNoter允许用户…

中小企业如何实现数字化转型发展?

数字化转型已成为企业未来发展的必然趋势,行业头部企业在此过程中持续投入自动化、信息化及数字化技术。虽然大多数系统投入不能仅基于短期投资回报率决策,且资源投入大见效慢、失败率也高,但数字化转型是不可逆转的过程,未来生存…

基于Skywalking的全链路跟踪实现

在前文“分布式应用全链路跟踪实现”中介绍了分布式应用全链路跟踪的几种实现方法,本文将重点介绍基于Skywalking的全链路实现,包括Skywalking的整体架构和基本概念原理、Skywalking环境部署、SpringBoot和Python集成Skywalking监控实现等。 1、Skywalki…

代码随想录算法训练营第四十五天丨 动态规划part08

139.单词拆分 思路 背包问题 单词就是物品,字符串s就是背包,单词能否组成字符串s,就是问物品能不能把背包装满。 拆分时可以重复使用字典中的单词,说明就是一个完全背包! 动规五部曲分析如下: 确定dp…

java网络通信:Springboot整合Websocket

网络通信 什么是webSocket?WebSocket 原理springboot整合websocket过程 网络通信三要素:ip地址(ipv4、ipv6)、端口号(应用程序的唯一标识)、协议(连接和通信的规则,常用:…

9 网关的作用

1、总结: 1.如果离开本局域网,就需要经过网关,网关是路由器的一个网口。 2.路由器是一个三层设备,里面有如何寻找下一跳的规则 3.经过路由器之后 MAC 头要变,如果 IP 不变,相当于不换护照的欧洲旅游&#…

Android:Type io.reactivex.android.R is defined multiple times

项目直接运行没有问题,但是打正式包会报这个错误, 错误的重点是io.reactivex.android.R这个引用的包与项目中引用的包冲突, 需要改成相同的版本 即可

Java中对象的比较:复写基类的equals+Comparble接口类的比较+比较器比较+PriorityQueue的比较+源码分析

文章目录 Java中对象的比较一、元素的比较二、对象的比较1.复写基类的equals2.基于Comparble接口类的比较3.基于比较器比较三种方法的对比 4. 集合框架中PriorityQueue的比较方式 Java中对象的比较 一、元素的比较 在Java中,基本类型的对象可以直接比较大小。 二、…

哪款手机便签软件支持存储录音文件并支持转文字?

手机便签类软件带有存储录音转文字功能是比较实用的,很多人通常会整理很多录音类型的文件,录音文件整合在一起后,后续有需要可以逐条点开播放收听。尤其是在工作中,当领导说一些重点时,大家无法借助灵活的大脑来成功的…