Jvm基础(一)

news2024/12/24 8:40:21

目录

  • 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.coloradmin.cn/o/1937100.html

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

相关文章

React基础学习-Day04

React基础学习-Day04 常见的钩子函数及基础使用方式 1.useState useState 是 React 的一个 Hook&#xff0c;用于在函数组件中添加状态。它返回一个状态变量和一个更新该状态的函数。与类组件的 this.state 和 this.setState 相对应&#xff0c;useState 让函数组件也能拥有…

【第10章】Spring Cloud之Nacos动态配置

文章目录 前言一、上下文1. 新增配置2. 启动类3. 效果 二、注解 ( 推荐 ) \color{#00FF00}{(推荐)} (推荐)1. 获取配置2. 测试2.1 未配置2.2 配置值2.3 修改值 总结 前言 这一章我们通过两个案例来学习Nacos动态配置&#xff0c;通过在控制台修改服务端配置文件值&#xff0c;…

linux环境交叉编译openssl库,以使Qt支持https

一.前言 Qt若需要支持https&#xff0c;则需要openssl的支撑,并且要注意&#xff0c;Qt不同版本会指定对应的openssl版本库&#xff0c;比方我用的Qt5.15.10他要求用的openssl版本是1.1.1&#xff0c;你就不能用其他版本&#xff0c;不然基本就是失败报错。 如何查看Qt对应ope…

TK秘籍:深度剖析机房IP与住宅IP的利与弊

大家好&#xff0c;今天我们来聊聊TikTok运营中的一个重要环节——IP地址的选择。 想象一下&#xff0c;你在TikTok上发布视频&#xff0c;就像是在一个热闹的市集上摆摊&#xff0c;而IP地址就是你的摊位位置。选对了位置&#xff0c;你的摊位就能吸引更多顾客&#xff0c;也…

浪漫情怀:红酒中的诗意与情感

在生活的点滴细节中&#xff0c;总有些元素能触动我们内心较柔软的地方&#xff0c;唤起那份深深的浪漫情怀。而红酒&#xff0c;便是这其中的一种神奇媒介。它以其不同的色泽、香气和口感&#xff0c;让人沉醉其中&#xff0c;感受那份诗意与情感的交织。今天&#xff0c;就让…

使用Kotlin Flow和协程开发高性能Android应用

使用Kotlin Flow和协程开发高性能Android应用:以电影业务为例 引言 在当今移动互联网快速发展的时代,用户对应用的性能和响应速度有了更高的要求。作为开发者,我们需要不断探索和采用新的技术来提升应用的性能和用户体验。Kotlin作为Android开发的首选语言,其协程和Flow特…

抖音/腾讯/百度ocpm深度回传如何操作?广告投放双出价的投放技巧?

要实现抖音、腾讯和百度的OCPM&#xff08;Optimized Cost Per Mille&#xff09;深度回传&#xff0c;可以通过借助第三方平台&#xff0c;例如&#xff08;转化宝&#xff09;实现广告数据精准回传&#xff0c;如此之外&#xff0c;在广告投放过程中还需要注重这些方面。 转化…

Python+Django+MySQL的新闻发布管理系统【附源码,运行简单】

PythonDjangoMySQL的新闻发布管理系统【附源码&#xff0c;运行简单】 总览 1、《新闻发布管理系统》1.1 方案设计说明书设计目标工具列表 2、详细设计2.1 登录2.2 程序主页面2.3 新闻新增界面2.4 文章编辑界面2.5 新闻详情页2.7 其他功能贴图 3、下载 总览 自己做的项目&…

云计算实训06——find、stat、touch、tree、scp、crontab指令相关应用

一、find命令 1.find的作用&#xff1a;对文件进行搜索 2. 基本语法&#xff1a; find [文件路径] [选项 选项的值 ] 3.常见的选项 -name 根据文件的名称搜索文件&#xff0c;支持通配符 * -type f 代表普通文件&#xff0c;-type d 代表目录 4.* 通配符 在 linux 系统…

QT--多页面、定时器和日期时间数据

多页面 widget.ui 负责实现一个页面; mian.cpp创建窗体对象,并监控上面的事件 窗口的显示和隐藏: 一个窗体,比如logpage widget,继承QWidget QWidget::show(); 显示该窗体 QWidget::hide(); 隐藏该窗体 页面间通信采用在main.cpp中创建connect槽函数。 代码如下 //main.c…

socket 收发TCP/UDP

一、c 个人测试记录&#xff0c;有问题还请指出&#xff0c;谢谢 参考&#xff1a;C开发基础之网络编程WinSock库使用详解TCP/UDP Socket开发_c udp使用什么库-CSDN博客 代码中Logger测试见文章&#xff1a; c中spdlog的使用/python中logger的使用-CSDN博客 1、main.cpp 收…

PE安装系统

前些天客户的电脑坏了,需要重装系统,我们的恢复光盘安装的时候,由于主板的原因,导致进入windows安装界面,鼠标键盘没有响应,自然也就无法正常安装了. 那我们只能换个方法,PE安装试试看,那么我们需要做哪些准备工作呢? 1.制作PE启动盘,网上很多制作工具,如""U启动,…

贪心算法总结(1)

一、贪心算法简介 常用方法&#xff1a;交换论证法、数学归纳法、反证法、分类讨论 二、柠檬水找零&#xff08;交换论证法&#xff09; . - 力扣&#xff08;LeetCode&#xff09; class Solution { public:bool lemonadeChange(vector<int>& bills) {int five0,t…

蜂窝物联云平台:一站式服务,智能生活从此开始!

蜂窝云平台 一、PC端展示与管理 GIS地图整合 在GIS地图上精确展示地块&#xff0c;轻松点选查看详细设备信息、实时监控和控制功能&#xff0c;以及基地的全方位介绍。 个性化定制界面 界面布局与功能展示均可按需求定制&#xff0c;打造独一无二的用户体验。 数据集中看板 将…

html网页使用tesseract实现OCR文字识别

即在前端实现OCR文字识别 1.前端代码 <!DOCTYPE html> <html lang"zh-CN"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>OCR文字识别…

C/C++ json库

文章目录 一、介绍1.1 json 介绍 二、C/C json 库选型2.1 选型范围2.2 jsoncpp2.2.2 jsoncpp 编译和交叉编译 2.3 rapidjson2.4 nlohmann/json2.5 sonic-cpp 五、常见问题5.1 jsoncpp 中关于浮点数的控制和中文显示问题5.2 jsoncpp序列化double类型时精度损失问题的解决办法 一…

JavaWeb JavaScript ① JS简介

目录 一、HTML&CSS&JavaScript的作用 二、前后端关联标签——表单标签 1.form标签 2.input标签 3.get/post提交的差异 4.表单项标签 5.布局相关标签 块元素——div 行内元素——span 三、CSS 1.CSS引入方式 方式1 行内式 方式2 内嵌式 方式3 外部样式表 2.CSS选择器 元…

AWS Certified Developer Associate备考笔记

AWS Certified Developer Associate备考笔记 缓慢更新中&#xff0c;如果你也正在关注该考试&#xff0c;请点赞后评论感兴趣的章节&#xff0c;可加快我的更新速度 &#x1f603; 文章目录 AWS Certified Developer Associate备考笔记一、IAM二、EC2三、EC2 Instance Storage…

Spring Boot项目中使用MyBatis Generator (MBG) 自动生成Mapper文件

Spring Boot项目中使用MyBatis Generator (MBG) 自动生成Mapper文件可以很大程度上减少编码。本文着重介绍如何在实战中使用MGB自动生成Mapper文件 1. 添加MyBatis Generator依赖 在pom.xml中添加必要的依赖 <dependency><groupId>org.mybatis.spring.boot</…