Jvm基础(一)

目录

  • JVM是什么
  • 运行时数据区域
    • 线程私有
      • 1.程序计数器
      • 2.虚拟机栈
      • 3.本地方法栈
    • 线程共享
      • 1.方法区
      • 2.堆
  • 二、对象创建
    • 1.给对象分配空间
      • (1)指针碰撞
      • (2)空闲列表
    • 2.对象的内存布局
      • 对象的组成
      • Mark Word
      • 类型指针
      • 实例数据:
      • 对齐填充
    • 对象的访问定位
      • 句柄法
  • 三、垃圾收集器和内存分配策略
    • 1.那些内存需要回收?
    • 2.什么时候回收
      • 《1》怎么判断对象死没死?
        • (1) 引用计数法,我称其为(脑门刻字法)
        • (2) 可达性分析算法,我称其为(平地长树法)
      • 《2》再谈引用
        • 强引用
        • 软引用
        • 弱引用
        • 虚引用
    • 3.如何回收
      • 垃圾收集理论基础
      • 垃圾收集算法
        • 标记-清除
        • 标记-复制
        • 标记-整理
      • 经典的垃圾收集器
        • CMS收集器(Concurrent Mark Sweep)
          • 步骤
        • G1收集器
          • 步骤

JVM是什么

Java虚拟机(Java Virtual Machine),用来运行.class的字节码文件。

运行时数据区域

Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域。如果程序书写不当会出现OutOfMemory Error内存溢出

线程私有

线程私有的数据区域,生命周期和线程相同

1.程序计数器

是当前线程所执行的字节码文件的行号指示器,此区域是Jvm规范中唯一不会出现OOM(OutOfMemory Error)的区域

2.虚拟机栈

存放的元素是栈帧
栈帧:每个方法被执行的时候Java虚拟机会创造一个栈帧,用于存放局部变量表、动态连接、方法出口等信息。每个方法的调用过程,就是栈帧从入栈到出栈的过程。

局部变量表:存储程序编译的时候的基本数据类型,和对象引用,内部以 局部变量槽(Slot) 作为存储单位,64位长度的数据类型会占用两个变量槽的方式,其余数据类型均只占用一个 局部变量槽

3.本地方法栈

什么是本地方法?

本地方法就是不使用java编写的,比如C++编写的程序,只是需要传递参数。

线程共享

1.方法区

实现: 一般处于堆中的永久代

目的: 已被虚拟机加载的类型信息、常量、静态变量、即时编译器编译后的代码缓存等数据。

元空间:位置在本地内存,jdk8以后把方法区中的信息全部转移到了元空间

2.堆

目的:用于存放对象实例

TLAB:(Thread Local Allocation Buffer):在堆中给每个线程一块属于自己的空间用于分配

二、对象创建

1.给对象分配空间

(1)指针碰撞

什么是指针碰撞?

假设Java堆中内存是绝对规整的,所有被使用过的内存都被放在一边,空闲的内存被放在另一边,中间放着一个指针作为分界点的指示器,那所分配内存就仅仅是把那个指针向空闲空间方向挪动一段与对象大小相等的距离,这种分配方式称为“指针碰撞”(Bump ThePointer)

什么情况下使用指针碰撞?

是否使用指针碰撞为对象分配空间,取决于java堆是否规整,而这又取决于垃圾收集器是否带有空间压缩整理能力。

(2)空闲列表

什么时候使用空闲列表

Java堆中的内存并不是规整的,已被使用的内存和空闲的内存相互交错在一起

什么是空闲列表?

虚拟机维护一个列表,记录上哪些内存块是可用的,在分配的时候从列表中找到一块足够大的空间划分给对象实例,并更新列表上的记录,这种分配方式称为“空闲列表”(Free List)。

2.对象的内存布局

对象的组成

对象由对象头、实例数据,对齐填充三部分组成,重点介绍一下对象头

首先对象头由:Mark Word和类型指针(指向对象类信息的一个指针)组成,如果对象是数组,那么对象头中还有一部分用来存放数组长度的区域。

Mark Word

**什么是Mark Word **
Mark Word是一个有着动态定义的数据结构,是用于存储对象自身的运行时数据,如哈 希码(HashCode)、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳等

例如
Mark Word的32个比特存储空间中的25个比特用于存储对象哈希码,4个比特用于存储对象分代年
龄,2个比特用于存储锁标志位,1个比特固定为0
在这里插入图片描述

如下:
Alt

类型指针

是一个指向对象所在类的指针

实例数据:

对象真正存储的用用信息

对齐填充

不是必然存在的,起到占位符的作用,使得对象的整个长度为8字节的整数倍

对象的访问定位

句柄法

句柄池:在java堆中划分出一部分
句柄法:Java栈本地变量表中的reference-----》句柄池------》方法区中的创建对象的类/对象实例数据
在这里插入图片描述

直接指针:Java栈本地变量表中的reference指向对象实例数据指向方法区中的创建对象的类
在这里插入图片描述

优点:访问少一次指针定位
缺点:如果很多reference都指向了一个对象实例,那么要更改对象实例的地址的时候,需要更改很多个reference

三、垃圾收集器和内存分配策略

1.那些内存需要回收?

堆和方法区

2.什么时候回收

简单来说是回收死亡的对象

《1》怎么判断对象死没死?

(1) 引用计数法,我称其为(脑门刻字法)

描述:在对象中添加一个引用计数器,每当有一个地方引用它时,计数器值就加一(在脑门上刻的字加1);当引用失效时,计数器值就减一;任何时刻计数器为零的对象就是不可能再被使用的。

缺点: 难以解决对象之间相互引用的问题

(2) 可达性分析算法,我称其为(平地长树法)

描述:可以使用引用链连接到GC Roots(地面)的对象,可以认为其是长在地上,该对象不会被回收,只有使用引用链连接不到GC Roots的对象(无根浮萍)才是需要被回收的。

可以被认为是GC Roots的对象

项目例子
·在虚拟机栈(栈帧中的本地变量表)中引用的对象譬如各个线程被调用的方法堆栈中使用到的参数、局部变量、临时变量等。
·在方法区中类静态属性引用的对象譬如Java类的引用类型静态变量。
·在方法区中常量引用的对象譬如字符串常量池(String Table)里的引用。
·在本地方法栈中JNI(即通常所说的Native方法)引用的对象。
·Java虚拟机内部的引用如基本数据类型对应的Class对象,一些常驻的异常对象(比如NullPointExcepiton、OutOfMemoryError)等,还有系统类加载器。
·所有被同步锁(synchronized关键字)持有的对象。
·反映Java虚拟机内部情况的JMXBean、JVMTI中注册的回调、本地代码缓存等。

《2》再谈引用

强引用

例子“Object obj=new Object()
只要强引用还在就垃圾收集器就永远不会被不回收

软引用

生命周期: 系统将要发生内存溢出时回收
描述对象: 还有用,但非必须的对象

例子

SoftReference<String> sr = new SoftReference<String>(new String("hello"));
System.out.println(sr.get());
弱引用

生命周期: 垃圾收集器一工作就会被回收
描述对象 : 非必须对象,但是它的强度比软引用更弱一些

例子

	WeakReference<String> sr = new WeakReference<String>(new String("hello"));System.out.println(sr.get());System.gc();                //通知JVM的gc进行垃圾回收System.out.println(sr.get());
虚引用

作用:被虚引用的对象在被垃圾收集器回收时会收到一个系统通知

3.如何回收

垃圾收集理论基础

强分代假说: 熬过越多次垃圾收集过程的对象就越难以消亡。
弱分带假说: 绝大多数对象都是朝生夕灭的
跨带引用理论假说: 跨带引用相对于同代引用来说仅占极少数。

垃圾收集算法

标记-清除

步骤:
算法分为“标记”和“清除”两个阶段:
首先标记出所有需要回收的对象,在标记完成后,统一回收掉所有被标记的对象,
也可以反过来,标记存活的对象,统一回收所有未被标记的对象。

缺点:
1.执行效率不稳定
2.内存碎片化严重

优点:
简单高效

标记-复制

算法描述

将可用内存按容量划分为大小相等的两块,每次只使用其中的一块。当这一块的内存用完了,就将还存活着的对象复制到另外一块上面,然后再把已使用过的内存空间一次清理掉。

优点: 简单高效
缺点: 是将可用内存缩小为了原来的一半

Alt
标记-复制算法的改进

改进理论: 针对具备“朝生夕灭”特点的对象,提出了一种更优化的半区复制分代策略,现在称为 “Appel式回收”

应用区域: 主要用于新生代收集器。

Appel式回收的具体做法:
是把新生代分为一块较大的Eden空间和两块较小的Survivor空间,每次分配内存只使用Eden和其中一块Survivor。发生垃圾搜集时,将Eden和Survivor中仍然存活的对象一次性复制到另外一块Survivor空间上,然后直接清理掉Eden和已用过的那块Survivor空间。HotSpot虚拟机默认Eden和Survivor的大小比例是8∶1,也即每次新生代中可用内存空间为整个新生代容量的90%(Eden的80%加上一个Survivor的10%),只有一个Survivor空间,即10%的新生代是会被“浪费”的。当然,98%的对象可被回收仅仅是“普通场景”下测得的数据,任何人都没有办法百分百保证每次回收都只有不多于10%的对象存活,因此Appel式回收还有一个充当罕见情况的“逃生门”的安全设计,当Survivor空间不足以容纳一次Minor GC之后存活的对象时,就需要依赖其他内存区域(实际上大多就是老年代)进行分配担保(Handle Promotion)。

分配担保: 存活数量超过Survivor的话,存活对象直接进入老年代
在这里插入图片描述

标记-整理

算法描述: 标记所有存活对象,让所有存活的对象都向内存空间一端移动,然后直接清理掉边界以外的内存

在这里插入图片描述

经典的垃圾收集器

CMS收集器(Concurrent Mark Sweep)

目的: 以获取最短回收停顿时间为目标的
基于标记-清除算法实现的
缺点:
1.CMS收集器对处理器资源非常敏感(和用户线程并发运行)
2.无法处理“浮动垃圾”(Floating Garbage)
3.会有大量空间碎片产生。
4.:要是CMS运行期间预留的内存无法满足程序分配新对象的需要,就会出现一次“并发失败”,会冻结用户线程的执行,临时启用Serial Old收集器来重新进行老年代的垃圾收集,导致停顿时间就很长了。

步骤

(1)初始标记(CMS initial mark)
(2)并发标记(CMS concurrent mark)
(3)重新标记(CMS remark)
(4)并发清除(CMS concurrent sweep)

由于在整个过程中耗时最长的并发标记和并发清除阶段中,垃圾收集器线程都可以与用户线程一起工作,所以从总体上来说,CMS收集器的内存回收过程是与用户线程一起并发执行的。

G1收集器

**实现方式:**收集器面向局部收集的设计思路和基于Region的内存布局形式。
主要面向服务端应用的垃圾收集器。
面向局部收集
基于Region
通过原始快照(SATB)算法来实现的

步骤

(1)初始标记
(2)并发标记
(3)最终标记
(4)筛选收回

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

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

相关文章

瑞芯微平台RK3568系统开发(2)Camera 开发1

1. 前言 1.1 RK3568硬件框图 1.2 开发流程 通过gstreamer/rockit来在rockchip平台上做multimedia的开发&#xff1a; vpu_service--> mpp --> gstreamer/ffmpeg --> app vpu_service&#xff1a;驱动 mpp&#xff1a;rockchip平台的视频编解码中间件,相关说明参考…

vue3+ts+vite+electron+electron-packager打包成exe文件

目录 1、创建vite项目 2、添加需求文件 3、根据package.json文件安装依赖 4、打包 5、electron命令运行 6、electron-packager打包成exe文件 Build cross-platform desktop apps with JavaScript, HTML, and CSS | Electron 1、创建vite项目 npm create vitelatest 2、添…

【解决方案】华普微汽车智能钥匙解决方案

一、方案概述 1.什么是被动式无钥匙进入 "被动式无钥匙进入"&#xff08;Passive Keyless Entry&#xff09;是一种用于车辆、建筑物或其他设施的访问控制系统。它利用无线射频技术自动判断用户是否接近&#xff0c;并进行身份识别以执行开锁或落锁动作&#xff0c…

LabVIEW操作系列1

系列文章目录 我的记录&#xff1a; LabVIEW操作系列 文章目录 系列文章目录前言五、特殊用法5.1 取值范围表示5.2 对输入值取值范围进行限定5.3 控制多个While循环停止运行。5.4 获取按钮上的文本5.5 获取按钮上的文本【进阶】 六、使用步骤1.引入库2.读入数据 七、其余功能7.…

nodejs与npm版本对应表

Node.js — Node.js 版本 (nodejs.org)

go语言day20 使用gin框架获取参数 使用自定义的logger记录日志

Golang 操作 Logger、Zap Logger 日志_golang zap-CSDN博客 目录 一、 从控制器中获取参数的几种形式 1&#xff09; 页面请求url直接拼接参数。 2&#xff09; 页面请求提交form表单 3&#xff09; 页面请求发送json数据&#xff0c;使用上下文对象c的BindJSON()方法接…

Java中static静态变量--继承等相关知识

目录 static 继承&#xff1a; 继承的特点&#xff1a; 案例&#xff1a;自己设计一个继承体系练习&#xff1a; 设计思想&#xff1a; 代码&#xff1a; 子类到底能继承父类的哪些类容&#xff1f; 成员变量内存的继承情况&#xff1a; 成员方法的内存继承情况&#x…

示例:WPF中如何处理TabControl页面绑定ItemsSource切换TabItem时UI数据没有持久保存的问题

一、目的&#xff1a;在WPF开发过程中&#xff0c;经常用到TabControl&#xff0c;也会遇到类似问题&#xff0c;用TabControl绑定数据源ItemsSource时&#xff0c;切换TabItem时&#xff0c;UI上的数据没有持久保存&#xff0c;本文介绍一种处理方式&#xff0c;可以做到缓存页…

矩阵管理系统有哪些功能?

在当今快节奏的数字时代&#xff0c;管理多个社交媒体账号或内容渠道可能是一项令人望而生畏的任务。这就是矩阵管理系统大显身手的地方。矩阵管理系统是一种高效的工具&#xff0c;它帮助我们轻松地管理多个内容发布点&#xff0c;就像指挥官控制着整个战场一样。下面&#xf…

C++·set与map容器(下)

本节把红黑树封装到set与map容器中去主要就是迭代器的自增自减&#xff0c;封装的大部分内容都展示到最后代码中了 1. 红黑树的改造 因为set容器只有关键码值&#xff0c;map容器中不仅要存关键码值&#xff0c;还要存关键码值对应的数据。但是红黑树只有一颗&#xff0c;我们…

【轨物方案】码头卸船机在线监测物联网解决方案

卸船机是利用连续输送机械制成能提升散粒物料的机头&#xff0c;或兼有自行取料能力&#xff0c;或配以取料、喂料装置&#xff0c;将散粒物料连续不断地提出船舱&#xff0c;然后卸载到臂架或机架并能运至岸边运输的地方送机系统去的专用机械。每年都要安排人员定期去现场巡检…

搭建DNS正向解析,反向解析+搭建DNS主从架构+搭建DNS多区域+时间同步

主要在局域网中配置&#xff0c;不存在外网 正向解析&#xff1a;域名解析为IP named.conf 解决权限 named.rfc1912.zones 解决解析方式 环境准备&#xff1a;三台机器都做下面的操作 基础配置&#xff1a;网络配置&#xff0c;关闭安全架构&#xff0c;关闭防火墙&#x…

3D模型可视化引擎HOOPS Luminate功能一览:实时渲染(二)

HOOPS Luminate是一款专为图像可视化设计的C编程工具包。它通过一个统一的集成API&#xff0c;全面覆盖了实时2D、实时3D以及照片级逼真渲染的图形功能。在处理大型数据组件的显示方面&#xff0c;HOOPS Luminate展现出了卓越的性能&#xff0c;并且具备高度的可定制性和灵活性…

一文带你读懂TCP

文章目录 1 TCP协议1.1 TCP 基础1.1.1 TCP 特性1.2.2 TCP连接数 1.2 TCP 头1.2.1 TCP 头格式1.2.2 MTU&#xff0c;MSS&#xff0c;分片传输 1.3 TCP 连接三路握手1.4 TCP 断开四次挥手1.5 SYN攻击和防范1.6 重传机制1.6.1 超时重传1.6.2 快速重传1.6.3 SACK 1.7 滑动窗口1.8 流…

VScode使用Github Copilot插件时出现read ECONNREST问题的解决方法

文章目录 read ECONNREST查看是否仍是 Copilot 会员查看控制台输出网络连接问题浏览器设置问题笔者的话 read ECONNREST 最近使用 Copilot 时一直出现 read ECONNREST 问题&#xff0c;这个表示连接被对方重置了&#xff0c;就是说在读取数据时连接被关闭。 我首先怀疑是不是…

springboo 整合 redis

springBoot 整合 redis starter启动依赖。—包含自动装配类—完成相应的装配功能。 引入依赖 <!--引入了redis整合springboot 的依赖--> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis&…

PostgreSQL的pg-collector工具

PostgreSQL的pg-collector工具 pg-collector 是一个用于 PostgreSQL 数据库的监控和数据收集工具。它主要用于收集 PostgreSQL 实例的性能指标、查询统计和日志信息&#xff0c;以便进行数据库性能分析和故障排查。通过收集这些数据&#xff0c;管理员可以更好地了解数据库的运…

盘点2024年网上很火的4个语音识别转文字工具。

语音识别转文字是一项非常实用的技术&#xff0c;可以帮助我们在会议记录中省去手动记录&#xff0c;在采访中迅速得到文字稿&#xff0c;在学习中快速生成课堂笔...运用十分广泛。但是很多人不知道要怎么转换&#xff0c;在这里我便给大家介绍几款效率非常高的语音转文字的工具…

python 裁剪图片

情况&#xff1a; 有时候看视频&#xff0c;看到一个漂亮的妹子&#xff0c;按下 Alt PrintScreen 进行截图之后&#xff0c;会把整个屏幕都截图。 需要适当剪裁一下。 每次打开 PS &#xff0c; 也太慢了。 所以写个代码&#xff0c; 快速处理。 效果对比&#xff1a; 原始…

轨道式智能巡检机器人,助力综合管廊安全运维

1 引言 当前城市综合管廊建设已经成为世界范围内的发展趋势&#xff0c;2017年5月住建部、发改委联合发布《全国城市市政基础设施建设“十三五”规划》&#xff0c;截至2017年4月底国内地下综合管廊试点项目已开工建设687 km&#xff0c;建成廊体260 km&#xff0c;完成投资40…