JVM-Java内存区域
运行时数据区:
1、程序计数器:
当前线程所执行的字节码指令的行号指示器。在Java虚拟机的概念模型里,字节码解释器的工作就是通过改变这个计数器的值来选取下一条需要执行的字节码指令,它是程序控制流的指示器,分支、循环、跳转、异常处理、线程恢复等基础功能都需要依赖这个计数器来完成。
线程私有,不会出现OutOfMemoryError异常。
2、Java虚拟机栈:
虚拟机栈描述的是Java方法执行的内存模型:每个方法被执行的时候,Java虚拟机都会创建一个栈帧用于存储局部变量表、操作数栈、动态连接、方法出口等信息。每一个方法被调用直至执行完毕的过程,就对应着一个栈帧在虚拟机中从入栈到出栈的过程。
线程私有。如果线程请求的栈深度大于虚拟机栈所允许的深度,将抛出StackOverflowError异常;如果Java虚拟机栈的容量可以动态扩展,当栈扩展时无法申请到足够的内存会抛出OutOfMemoryError异常。
3、本地方法栈:
本地方法栈与虚拟机栈所发挥的作用是非常相似的,其区别只是虚拟机栈为虚拟机执行Java方法(也是字节码)服务,而本地方法栈则是为虚拟机使用到的本地(Native)方法服务。
4、Java堆:
Java堆是虚拟机所管理的内存中最大的一块。“几乎”所有的对象实例和数组都在这里分配内存。Java堆是垃圾收集器管理的内存区域,因此一些资料中把它称作“GC堆”。
线程共享。如果在Java堆中没有内存完成实例分配,并且堆也无法扩展时,Java虚拟机会抛出OutOfMemoryError异常。
5、方法区:
方法区用来存储已被虚拟机加载的类型信息、常量、静态变量、即时编译器编译后的代码缓存等数据。这块内存回收的主要目标是针对常量池的回收和对类型的卸载。
线程共享。如果方法区无法满足新的内存分配的需求时,将会抛出OutOfMemoryError异常。
永久代:
在JDK8之前,许多Java程序员都习惯在HotSpot虚拟机上开发、部署程序,很多人都更愿意把方法区称为“永久代”。但本质上二者是不等价的。
元空间:
在JDK6,HotSpot团队逐步改为采用本地内存的方法来实现方法区的计划了。到了JDK8,终于完全废除了永久代的概念,改用与JRockit、J9一样在本地内存中实现的元空间来代替,把JDK7中永久代还剩余的内容(主要是内存信息)全部移到元空间中。
为什么用元空间代替永久代?
1、避免OOM。使用永久代导致Java应用更容易遇到内存溢出的问题:永久代有-XX:MaxPermSize的上限,即使不设置也有默认大小。元空间存在本地内存中,有系统实际可用空间来控制,当然也可以控制大小-XX:MaxMetaSpaceSize。
2、提高GC性能:永久代会位GC带来不必要的复杂度,而且回收效率偏低。
3、合并HotSpot和JRockit:在Oracle收购BEA取得JRockit的所有权后,准备把JRockit中的优秀功能移植到HotSpot虚拟机时,因为两者都对方法区的实现的差异而面临很多困难。
对象的创建:
1、类加载:
当Java虚拟机遇到一条字节码new指令时,首先将去检查这个指令的参数能否在常量池中定位到一个类的符号引用,并且检查这个符号引用代表的类是否已被加载、解析和初始化过。如果没有,那必须先执行相应的类加载过程。
2、分配内存:
在类加载检查通过后,虚拟机将为新生对象分配内存。对象所需的内存大小在类加载完成后就可以完全确定,为对象分配空间的任务实际上便等于把一块确定大小的内存块从Java堆中划分出来。
分配内存的方法:
指针碰撞:如果Java堆中的内存是绝对规整的,所有被使用过内存都被放到一边,空闲的内存被放到另一遍,中间放着一个指针作为分界点的指示器,那所分配的内存就仅仅是把那个指针向空闲空间的方向挪动一段与对象大小相等的距离。
空闲列表:如果Java堆中的内存并不是规整的,已经使用过内存和空闲的内存交错在一起,虚拟机必须维护一个列表,记录上哪些内存块是可用的,在分配的时候从列表中找到一块足够大的空间划分给对象实例,并更新列表上的记录。
并发情况下产生的问题:
1、对分配内存空间的动作进行同步处理,实际上虚拟机采用CAS配上失败重试的方式保证更新操作的原子性。
2、把内存分配的动作按照线程划分在不同的空间之中进行,即每个线程在Java堆中预先分配一小块内存,称为本地线程分配缓冲(TLAB),哪个线程需要分配内存,就在哪个线程的本地缓冲区中分配,只有本地缓冲区用完了,分配新的缓存区时才需要同步锁定。虚拟机是否使用TLAB,通过-XX+:-UseTLAB参数来设定。
3、初始化零值:
内存分配完后,虚拟机必须将分配到的内存空间(不包括对象头)都初始化为零值,如果使用了TLAB,这项工作也可以提前到TLAB分配时顺便进行。这步操作保证了对象的实例字段在Java代码中不赋初值也可以直接使用。
4、设置对象头:
接下来Java虚拟机堆对象进行必要的设置,例如这个对象时哪个类的实例等。
5、执行<init>()方法:
上述操作完成之后,从虚拟机的视角来看,一个新的对象已经产生了。但是从Java程序的视角看来,对象的创建才刚刚开始。一般来说,new指令之后会接着执行<init>()方法,按照程序员的意愿对对象进行初始化,这样一个真正可用的对象才算完全被构造出来。
对象的内存布局:
对象在堆内存中的存储布局可以划分为三个部分:对象头、实例数据和对齐填充。
1、对象头:
HotSpot虚拟机的对象头包括两类信息:
用于存储对象自身的运行时数据:如哈希码(HashCode)、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳等。
类型指针:即对象指向它的类型元数据的指针,Java虚拟机通过这个指针来确定该对象是哪个类的实例。但并不是所有的虚拟机实现都必须在对象数据上保留类型指针,换句话说,查找对象的元数据信息并不一定要经过对象本身。
2、实例数据:
实例数据部分是对象真正存储的有效信息,即我们在程序代码里面所定义的各种类型的字段内容,无论是从父类继承下来的,还是在子类中定义的字段都必须记录起来。
3、对齐填充:
对齐填充并不是必然存在的,也没有特殊的含义,仅仅起着占位符的作用。由于HotSpot虚拟机的自动内存管理系统要求对象的起始位置必须是8字节的证书倍,换句话说就是任何对象的大小都必须是8字节的整数倍。因此,如果对象实例数据部分没有对齐的话,就需要通过对齐填充来补全。
对象的访问定位:
我们的Java程序会通过栈上的reference数据来操作堆上的具体对象。主流的访问方式主要有使用句柄和直接指针两种:
1、使用句柄:
如果使用句柄访问的话,Java堆中可能会划分出一块内存来作为句柄池,reference中存储的就是对象的句柄地址,而句柄中包含了对象实例数据与类型数据各自具体的地址信息。
优点:使用句柄来访问最大的好处就是reference中存储的是稳定的句柄地址,在对象被移动时只会改变句柄中的实例数据指针,而reference本身不需要被修改。
2、直接指针:
如果使用直接指针访问的话,Java堆中的对象的内存布局就必须考虑如何放置访问类型数据的相关信息,reference中存储的直接就是对象的地址,如果只是访问对象本身的话,就不需要多一次间接访问的开销。
优点:使用直接指针来访问的最大好处就是速度更快,它节省了一次指针定位的时间开销。
相关文章:
JVM-Java内存区域
运行时数据区:1、程序计数器:当前线程所执行的字节码指令的行号指示器。在Java虚拟机的概念模型里,字节码解释器的工作就是通过改变这个计数器的值来选取下一条需要执行的字节码指令,它是程序控制流的指示器,分支、循环…...
毕业季,毕业论文查重,paper系列五个免费查重网站推荐
推荐五个常用的免费查重网站 注意: (1)这些网站基本上都可以通过关注公众号或者转发等来获取免费查重机会,但有些也会有字数限制。每个网站的数据库可能不同,所以建议大家多换几个平台查一查,反正是免费的…...
破解票房之谜:为何高票房电影绕不过“猫眼们”?
如此火爆的春节档很多,如此毁誉参半的春节档鲜有。2023开年,集齐张艺谋、沈腾的《满江红》,以及有票房前作打底的《流浪地球2》接连两部春节档电影票房进入前十,为有些颓靡的中国电影市场注入了一针“强心剂”。与票房同样热闹起来…...
订单服务-----遇到的问题及解决方案
订单服务的问题及解决方案问题1:Feign远程调用时丢失请求头编辑出现这个Feign远程调用时丢失请求头的问题是因为Feign在远程调用的时候会创建一个新的请求,但是这个新的请求里啥都没有,没有cookie值,而这个cookie值里有成功登录后…...
项目经理如何度量项目?及项目度量指标实例【静说】
度量项目是项目经理的一个重要职责,通过度量项目,项目经理可以了解项目的进展情况,及时发现问题并采取相应的措施,以确保项目能够按时、按质、按预算完成。 分享给大家一些常见的项目度量指标: 1. 项目进度ÿ…...
我们应该如何优雅的处理 React 中受控与非受控
引言 大家好,我是19组清风。有段时间没有和大家见面了,最近因为有一些比较重要的事情(陪女朋友和换了新公司)在忙碌所以销声匿迹了一小段时间, 后续会陆陆续续补充之前构建 & 编译系列中缺失的部分,提…...
力扣热题100Day06:20. 有效的括号,21. 合并两个有序链表,22. 括号生成
20. 有效的括号 题目链接:20. 有效的括号 - 力扣(Leetcode) 思路:使用栈 (1)遇到左括号就将其对应的右括号压入到栈中 (2)如果遇到右括号 a. 如果弹出的元素与当前不等ÿ…...
【Yolov5】保姆级别源码讲解之-推理部分detect.py文件
推理部分之detect.py文件讲解1.下载Yolov5的源码2. 主函数讲解3.文件标头的注释4. main函数的5. run函数5.1 第一块参数部分5.2第二块,传入数据预处理5.3 第三块创建文件夹5.4 第四块 加载模型的权重5.5 第五块 Dataloader 加载模块5.6 第六块 推理部分 Run inferen…...
无重叠区间-力扣435-java贪心策略
一、题目描述给定一个区间的集合 intervals ,其中 intervals[i] [starti, endi] 。返回 需要移除区间的最小数量,使剩余区间互不重叠 。示例 1:输入: intervals [[1,2],[2,3],[3,4],[1,3]]输出: 1解释: 移除 [1,3] 后,剩下的区间没有重叠。…...
Python使用VTK对容积超声图像进行体绘制(三维重建)
目录VTK简介什么是体绘制?体绘制效果图流程CodeQ&AReferenceVTK简介 VTK(Visualization Toolkit)是一个用于3D计算机图形学、图像处理和可视化的开源软件包。它包括一组C类和工具,可以让用户创建和处理复杂的3D图形和数据可视…...
JAVA设计模式之工厂模式讲解
目录 前言 开始表演 前言 Java中使用工厂模式的主要原因是为了实现代码的灵活性和可维护性。工厂模式是一种创建型设计模式,它提供了一种将对象的创建和使用进行分离的方式。具体来说,工厂模式可以将对象的创建过程封装在一个独立的工厂类中ÿ…...
近万字概述L3及以上自动驾驶故障运行和故障安全机制
本文描述了对ADS的FO和FS机制的评估方法。当系统不能按预期运行时,ADS将使用FO和FS机制。这些机制使ADS能够在最大程度上达到使车辆及其乘员脱离危险的MRC。定义、测试和验证实现MRC的FO和FS策略是确保ADS安全运行和部署的重要步骤。 MRC在SAE J3016中被定义为: 用户或ADS在…...
kafka入门到精通
文章目录一、kafka概述?1.定义1.2消息队列1.2.1 传统消息队列的使用场景1.2.2 消息队列好处1.2.3 消息队列两种模式1.3 kafka基础架构二、kafka快速入门1.1使用docker-compose安装kafka1.2测试访问kafka-manager1.3 查看kafka版本号1.4 查看zookeeper版本号1.5 扩展…...
es-09模糊查询
模糊查询 前缀搜索:prefix 概念:以xx开头的搜索,不计算相关度评分。 注意: 前缀搜索匹配的是term,而不是field。前缀搜索的性能很差前缀搜索没有缓存前缀搜索尽可能把前缀长度设置的更长 语法: GET <ind…...
57 - 深入解析任务调度
---- 整理自狄泰软件唐佐林老师课程 文章目录1. 问题1.1 思考1.2 实例分析:问题分析及解决2. 深入讨论2.1 任务调度的定义2.2 关于调度算法的分类2.3 什么时候进行任务调度2.4 任务的分类2.5 关于优先级调度2.6 问题2.7 调度算法的终极目标2.8 课后扩展1. 问题 系统…...
CAN总线开发一本全(3) - 微控制器集成的FlexCAN外设
CAN总线开发一本全(3) - 微控制器集成的FlexCAN外设 苏勇,2023年2月 文章目录CAN总线开发一本全(3) - 微控制器集成的FlexCAN外设引言硬件外设模块系统概要总线接口单元 - 寄存器清单数据结构 - 消息缓冲区MB初始化过…...
Elasticsearch7.8.0版本进阶——段合并
目录一、段的概述1.1、段的概念1.2、段的缺点1.3、如何解决段数量暴增问题二、段合并的流程三、段合并的注意事项一、段的概述 1.1、段的概念 每一 段 本身都是一个倒排索引。 1.2、段的缺点 由于自动刷新流程每秒会创建一个新的段 ,这样会导致短时间内的段数量…...
Java版贪食蛇游戏
技术:Java等摘要:近年来Java作为一种新的编程语言,以其简单性、可移植性和平台无关性等优点,得到了广泛地应用,特别是Java与万维网的完美结合,使其成为网络编程和嵌入式编程领域的首选编程语言。MyEclipse是…...
2023年度数学建模竞赛汇总
本人7年数学建模竞赛经验,历史获奖率百分之百。团队成员都是拿过全国一等奖的硕博,有需要数模竞赛帮助的可以私信我。 下面主要列几年一些比较有含金量的数学建模竞赛(按比赛时间顺序) 1. 美国大学生数学建模竞赛 报名时间&…...
了解Python语言和版本
1.1 任务1了解Python语言和版本 Python 语言的名字来自于一个著名的电视剧"Monty Pythons Flying Cireus",Python之父 Guido van Rossum是这部电视剧的狂热爱好者,所以把他设计的语言命名为Python。 Python 是一门跨平台、开源、免费的解释型高级动态编…...
Xshell远程连接Kali(默认 | 私钥)Note版
前言:xshell远程连接,私钥连接和常规默认连接 任务一 开启ssh服务 service ssh status //查看ssh服务状态 service ssh start //开启ssh服务 update-rc.d ssh enable //开启自启动ssh服务 任务二 修改配置文件 vi /etc/ssh/ssh_config //第一…...
Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)
文章目录 1.什么是Redis?2.为什么要使用redis作为mysql的缓存?3.什么是缓存雪崩、缓存穿透、缓存击穿?3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...
mongodb源码分析session执行handleRequest命令find过程
mongo/transport/service_state_machine.cpp已经分析startSession创建ASIOSession过程,并且验证connection是否超过限制ASIOSession和connection是循环接受客户端命令,把数据流转换成Message,状态转变流程是:State::Created 》 St…...
Linux相关概念和易错知识点(42)(TCP的连接管理、可靠性、面临复杂网络的处理)
目录 1.TCP的连接管理机制(1)三次握手①握手过程②对握手过程的理解 (2)四次挥手(3)握手和挥手的触发(4)状态切换①挥手过程中状态的切换②握手过程中状态的切换 2.TCP的可靠性&…...
定时器任务——若依源码分析
分析util包下面的工具类schedule utils: ScheduleUtils 是若依中用于与 Quartz 框架交互的工具类,封装了定时任务的 创建、更新、暂停、删除等核心逻辑。 createScheduleJob createScheduleJob 用于将任务注册到 Quartz,先构建任务的 JobD…...
[10-3]软件I2C读写MPU6050 江协科技学习笔记(16个知识点)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16...
【Zephyr 系列 10】实战项目:打造一个蓝牙传感器终端 + 网关系统(完整架构与全栈实现)
🧠关键词:Zephyr、BLE、终端、网关、广播、连接、传感器、数据采集、低功耗、系统集成 📌目标读者:希望基于 Zephyr 构建 BLE 系统架构、实现终端与网关协作、具备产品交付能力的开发者 📊篇幅字数:约 5200 字 ✨ 项目总览 在物联网实际项目中,**“终端 + 网关”**是…...
12.找到字符串中所有字母异位词
🧠 题目解析 题目描述: 给定两个字符串 s 和 p,找出 s 中所有 p 的字母异位词的起始索引。 返回的答案以数组形式表示。 字母异位词定义: 若两个字符串包含的字符种类和出现次数完全相同,顺序无所谓,则互为…...
安全突围:重塑内生安全体系:齐向东在2025年BCS大会的演讲
文章目录 前言第一部分:体系力量是突围之钥第一重困境是体系思想落地不畅。第二重困境是大小体系融合瓶颈。第三重困境是“小体系”运营梗阻。 第二部分:体系矛盾是突围之障一是数据孤岛的障碍。二是投入不足的障碍。三是新旧兼容难的障碍。 第三部分&am…...
C#中的CLR属性、依赖属性与附加属性
CLR属性的主要特征 封装性: 隐藏字段的实现细节 提供对字段的受控访问 访问控制: 可单独设置get/set访问器的可见性 可创建只读或只写属性 计算属性: 可以在getter中执行计算逻辑 不需要直接对应一个字段 验证逻辑: 可以…...
