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.mzph.cn/pingmian/48051.shtml

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

相关文章

Python基础知识——(005)

文章目录 P21——20. 比较运算符 P22——21. 逻辑运算符 P23——22. 位运算和运算符的优先级 P24——23. 本章总结和章节习题 P21——20. 比较运算符 示例3-17—比较运算符的使用&#xff1a; P22——21. 逻辑运算符 示例3-18—逻辑运算符的使用&#xff1a; print(True and T…

【C语言】逗号运算符详解 - 《不起眼的 “逗号”》

目录 C语言逗号运算符详解1. 逗号运算符的定义1.1 基本语法1.2 执行顺序 2. 逗号运算符的用法2.1 用于循环2.1.1 示例 2.2 用于表达式组合2.2.1 示例 3. 逗号运算符的应用场景3.1 宏定义3.1.1 示例 3.2 条件运算符中的应用3.2.1 示例 4. 总结5. 参考文献6. 结束语 C语言逗号运算…

UBUNTU22 安装QT5.15.2 记录

安装QT预置安装软件包 sudo apt install gcc sudo apt install g sudo apt install clang sudo apt install clang sudo apt install make sudo snap install cmake --classic sudo apt-get install build-essential sudo apt install libxcb-xinerama0 #安装OpenGL核心库 su…

天途无人机林业应用解决方案

林业应用现状分析 森林环境较为复杂&#xff0c;人员无法快速到达现场&#xff0c;工作人员通常会面临监控盲区&#xff0c;林区爬山涉水困难多&#xff1b;森林防火重要性不可忽视&#xff0c;2019年全国共发生森林火灾2345起&#xff0c;森林防火仍为重中之重&#xff1b;环…

go语言的基础语法

基础语法 与python、vue等类似&#xff0c;go语言也分常量和变量等&#xff0c;常量用const(不可变)和变量var(可变)定义 常量 常量中的数据类型只可以是布尔型、数字型&#xff08;整数型、浮点型和复数&#xff09;和字符串型&#xff0c;值不可更改&#xff0c;表达式只支…

(南京观海微电子)——boost电路原理及作用

BOOST升压电路 boost升压电路是六种基本斩波电路之一&#xff0c;是一种开关直流升压电路&#xff0c;它可以使输出电压比输入电压高。主要应用于直流电动机传动、单相功率因数校正&#xff08;PFC&#xff09;电路及其他交直流电源中。 BOOST升压电源是利用开关管开通和关断的…

Excel表格导出

1.后端 /*** 导出一对一线下课签到表* param response* param selectedArriveTime* param selectedClassRoom*/RequestMapping(value "/exportExcel", method {RequestMethod.GET})public void exportExcel(HttpServletResponse response, String selectedArriveTi…

【网络安全的神秘世界】Error:Archives directory /var/cache/apt/archives/partial is missing.

&#x1f31d;博客主页&#xff1a;泥菩萨 &#x1f496;专栏&#xff1a;Linux探索之旅 | 网络安全的神秘世界 | 专接本 | 每天学会一个渗透测试工具 ✨问题描述 在kali中想要安装beef-xss软件包时&#xff0c;发生如下报错&#xff1a; Error: Archives directory /var/cac…

我在高职教STM32——串口通信(3)

大家好&#xff0c;我是老耿&#xff0c;高职青椒一枚&#xff0c;一直从事单片机、嵌入式、物联网等课程的教学。对于高职的学生层次&#xff0c;同行应该都懂的&#xff0c;老师在课堂上教学几乎是没什么成就感的。正因如此&#xff0c;才有了借助 CSDN 平台寻求认同感和成就…

编织文字之美:WebKit的CSS文本格式化能力全解析

编织文字之美&#xff1a;WebKit的CSS文本格式化能力全解析 在网页设计中&#xff0c;文本不仅是传递信息的媒介&#xff0c;更是展现美学的重要元素。WebKit&#xff0c;作为Safari、QQ浏览器等众多浏览器的内核&#xff0c;提供了强大的CSS文本格式化支持。通过CSS&#xff…

Kubernetes Service 之 LoadBalancer

Kubernetes 之 LoadBalancer 定义 负载均衡器 (LoadBalancer) 是 Kubernetes 中用来对外暴露 Service 服务的&#xff0c;它可以将服务集中到一个公共 IP 上。我们常用 MetalLB 作为自建均衡器。 使用 安装 MetalLB kubectl apply -f https://raw.githubusercontent.com/m…

pandas库方法汇总介绍

目录 1. assign() 新增一列 1. assign() 新增一列 >>> df pd.DataFrame({temp_c: [17.0, 25.0]}, ... index[Portland, Berkeley]) >>> dftemp_c Portland 17.0 Berkeley 25.0Where the value is a callable, evaluated on df: &…

vue slot:为什么 $slots 无值而 $scopedSlots 有值?

在 Vue.js 中&#xff0c;$slots 和 $scopedSlots 是组件实例上用于访问插槽内容的两个属性&#xff0c;但它们各自有不同的用途和表现方式&#xff0c;特别是在处理作用域插槽&#xff08;scoped slots&#xff09;时。 $slots $slots 是一个包含所有插槽内容的对象。对于普…

使用Python爬虫下载视频源码

一、引言(●ˇ∀ˇ●) 在当今互联网时代&#xff0c;视频内容已成为人们获取信息和娱乐的重要方式。有时&#xff0c;我们可能希望将这些视频下载到本地&#xff0c;以便在没有网络的情况下观看。本文将介绍如何使用Python编写一个简单的爬虫。 二、环境准备&#x1f618; 在…

Nginx部署前端项目尝试 - windows版

前端还是要学一点服务器端的东西&#xff0c;才能更好的理解一些知识 1、项目打包 生成dist 2、下载nginx解压&#xff0c;start nginx 启动 浏览器输入 localhost 显示如下页面表示启动成功 3、配置nginx server {listen 8080;# ip 不要加http 前后不要加 /server_name…

结合金融场景的Scipy模块编程

结合金融场景的Scipy模块编程 数据链接&#xff1a;https://pan.baidu.com/s/1VMh8-4IeCUYXB9p3rL45qw 提取码&#xff1a;c6ys import numpy as np import pandas as pd import statsmodels import matplotlib.pyplot as plt from pylab import mpl mpl.rcParams[font.sans-se…

蓝牙耳机推荐哪个品牌?四款必入热门蓝牙耳机品牌推荐

面对市场上琳琅满目的蓝牙耳机品牌和型号&#xff0c;选择一款合适的蓝牙耳机可能会令人感到困惑&#xff0c;蓝牙耳机推荐哪个品牌&#xff1f;为了帮助大家做出明智的决策&#xff0c;我将带来四款必入热门蓝牙耳机品牌推荐&#xff0c;均是我自用还不错的&#xff0c;大家可…

VisualRules-Web案例展示(一)

VisualRules单机版以其卓越的功能深受用户喜爱。现在&#xff0c;我们进一步推出了VisualRules-Web在线版本&#xff0c;让您无需安装任何软件&#xff0c;即可在任何浏览器中轻松体验VisualRules的强大功能。无论是数据分析、规则管理还是自动化决策&#xff0c;VisualRules-W…

【JavaScript 算法】堆排序:优先队列的实现

&#x1f525; 个人主页&#xff1a;空白诗 文章目录 一、算法原理堆的定义堆排序的步骤 二、算法实现构建最大堆注释说明&#xff1a; 三、应用场景四、总结 堆排序&#xff08;Heap Sort&#xff09;是一种基于堆数据结构的排序算法&#xff0c;具有较好的时间复杂度表现。堆…

JDBC常见用法

JDBC中主要的类及常用方法 Class类 Class类全称java.lang.Class&#xff0c;Java程序运行时会自动创建程序中的每个类的Class对象&#xff0c;通过Class类的方法&#xff0c;可以得到程序中每个类的信息。Class类方法主要包括&#xff1a; public static Class forName(S…