JVM快速入门学习笔记(四)

news2025/1/13 19:44:03

15.GC :垃圾回收机制

垃圾回收的区域只有在堆里面(方法区在堆里面)

在这里插入图片描述

15.1 垃圾回收 = GC

JVM 在进行垃圾回收(GC)时,并不是堆这三个区域统一回收。大部分时候,回收都是新生代~
  1.新生代
  2.幸存区(form,to)
  3.老年区

GC 两种类:轻GC(普通GC),重GC (全局GC)

轻GC 指针对 新生代 和 偶尔走一下 幸存区。

重GC 全部清完。

题目(重点):
  1.JVM的内存模型和分区~详细到每一个区放什么?
  2.堆里面的分区有哪些?
  3.GC的算法有哪些?
    标记清除法
    标记整理
    复制算法
    引用计数法
    怎么用的?
  4.轻GC 和 重GC 分别再什么时候发生?

15.2 引用计数法

假设我对象A 用了 一次就给它加上1
  假设我对象B 用了 两次就给它加上2
  假设我对象C 没有使用 就是 0

引用计数法就是给每个对象分配一个计数器

假设C 对象为 0,它就要被清除出去了

JVM 现在一般不采用这种方式,不高效。

在这里插入图片描述

15.3 复制算法

  • -XX:MaxTenuringThreshold=15 设置进入老年代的存活次数条件(动态调整)

在这里插入图片描述

一个对象怎么从新生代变成老年代(重点)

JVM新创建的对象(除了大对象外)会被存放在新生代,默认占1/3堆内存空间,由于JVM频繁的创建对象,所以新生代会频繁触发Minor GC进行垃圾回收。新生代又分为Eden区,survivorForm区和survivorTo区。

在这里插入图片描述

  1. 当伊甸园的空间填满时,程序又需要创建对象时,JVM 的垃圾回收器将对伊甸园区进行垃圾回收(Minor GC),将伊甸园区中的不再被引用的对象进行销毁.再加载新的对象放到伊甸园区
  2. 然后将伊甸园区中上一次垃圾回收的幸存者移动到幸存者 0 区(From)
  3. 如果再次触发垃圾回收,此时上次幸存下来存放到幸存者 0 区的对象,如果没有回收, 就会被放到幸存者 1 区(To)
  4. 如果再次经历垃圾回收,此时会重新放回幸存者 0 区,接着再去幸存者 1 区,对象在幸存者区中每熬过一次MinorGC,年龄就加一
  5. 什么时候去养老区呢?对象的年龄达到老年代标准,默认是 15 次,也可以设置参数(XX:MaxTenuringThreshold),最大值为 15
  6. 在老年区,相对悠闲,当养老区内存不足时,再次触发 Major GC,进行养老区的内存清理.
  7. 若养老区执行了 Major GC 之后发现依然无法进行对象保存,就会产生 OOM 异常:Java.lang.OutOfMemoryError:Java heap space
  8. 在这里插入图片描述

复制算法的优缺点

  • 好处:没有内存的碎片,内存效率高
  • 坏处:浪费了内存空间(一个幸存区永远是空的);假设对象100%存活,复制成本很高

复制算法最佳使用场景:对象存活度较低 的时候,新生区~。

15.4 标记清除算法

扫描这些对象,对活着的对象进行标记
清除:对没有标记的对象,进行清除

在这里插入图片描述

优点:不需要额外的空间
缺点:两次扫描严重浪费时间,会产生内存碎片。

15.5 标记压缩

在这里插入图片描述

本质是再次扫描,将标记了的内存碎片排序到一起

15.6 总结:

内存效率:复制算法 > 标记清除算法 > 标记压缩算法(时间复杂度)
  内存整齐度:复制算法 = 标记压缩算法 > 标记清除算法
  内存利用率: 标记压缩算法 = 标记清除算法 > 复制算法

没有最优算法吗?
  没有;
  没有最好的算法,只有最合适的算法~ ---->GC: 分代收集算法
  每一代用合适的算法就好了。

年轻代: (大部分的对象都在这里都死了)
  存活率低
  复制算法

老年代
  存活率高,区域大
  标记清除 + 标记压缩 混合实现

16. Java垃圾回收的原理与触发时机

16.1 Young GC(Minor GC)

什么时候会触发Minor GC?

  1. 大多数情况下,对象在年轻代中的Eden区进行分配,若Eden区没有足够空间,就会触发YGC(Minor GC)。

16.2 Full GC(Major GC)

FGC处理的区域包括新生代和老年代。

什么时候会触发Full GC?

  1. 老年代的内存使用率达到了一定阈值(默认是92% 通过-XX:MaxTenuringThreshoId设置)
    • 情景1:Survivor区进行了15次清理后还没清理的对象,则放到老年代。
      1. 次数这个阈值是可以设置的:-XX:MaxTenuringThreshold(默认是15)
    • 情景2:Minor GC时的检查
      1. 执行Minor GC时,JVM会先检查Survivor空间是否够用
        1. 如果够用则直接进行Minor GC
        2. 如果不够用,则检查老年代最大连续可用空间是否大于新生代的总和或者历次晋升到老年代的对象的平均大小
          1. 如果大于,则直接执行Minor GC(这个时候执行是没有风险的)。
          2. 如果小于,则直接执行Full GC
      2. JDK7及之后,空间分配担保参数:-XX:HandlePromotionFailure就失效了,无需考虑这个。
    • 情景3:使用了大对象
      1. 大对象会直接进入老年代。比如:一次加载过多数据到内存(比如SQL查询未分页),导致大对象进入老年代。
      2. 相关参数:-XX:PretenureSizeThreshold。若对象大小大于此值,就会绕过新生代, 直接在老年代中分配
  2. Metaspace(元空间)扩容到了-XX:MetaspaceSize 参数的指定值。(元空间在空间不足时会进行扩容)
  3. 程序执行了System.gc()
    1. 只是建议JVM执行FGC,并不一定会执行
  4. jmap 加了:live参数
    1. 例如:
    2. jmap -histo:live <pid>
    3. jmap -dump:live,format=b,file=heap.bin <pid>
  5. 其他
    1. 上一次GC之后Heap的各域分配策略动态变化
    2. RMI等的定时触发
    3. YGC时的悲观策略

16.3 System.gc()

​ 不要频繁使用gc函数。建议是:保持代码健壮(记得将不用的变量置为null),让虚拟机去管理内存

​ System.gc():提醒虚拟机进行垃圾回收,回不回收由虚拟机决定。若虚拟机决定回收,也不是立刻进行回收,它是异步的。当然,System.gc()也不是一点用也没有,当执行System.gc()之后,还是能一定程度影响垃圾回收的。如下所示:

17. JMM

  1. 什么是JMM? :百度

    java内存模型 Java Memory Model,它干嘛的? 学习途径:官方,其他人的博客,教学视频

​ 作用:缓存一致性协议,用于定义数据读写的规则

​ JMM定义了线程工作内存和主内存之间的抽象关系:线程之间的共享变量存储在主内存中, 每个线程都有一个**私有的本地变量内存。

在这里插入图片描述

解决共享对象可见性这个问题:volilate

17.1 volilate

Volatile关键字的作用主要有如下两个:

  1. 线程的可见性:当一个线程修改一个共享变量时,另外一个线程能读到这个修改的值。
  2. 顺序一致性:禁止指令重排序。
  3. 保证简单操作的原子性,如赋值操作等,像i++这种复杂的复合操作无法保证原子性。

底层原理

被volatile修饰的变量被修改时,会将修改后的变量直接写入主存中,并且将其他线程中该变量的缓存置为无效,从而让其它线程对该变量的引用直接从主存中获取数据,这样就保证了变量的可见性

volatile可见性的实现是借助了CPU的lock指令,lock指令在多核处理器下,可以将当前处理器的缓存行的数据写回到系统内存,同时使其他CPU里缓存了该内存地址的数据置为无效。通过在写volatile的机器指令前加上lock前缀,使写volatile具有以下两个原则:

  • 写volatile时处理器会将缓存写回到主内存。
  • 一个处理器的缓存写回到内存,会导致其他处理器的缓存失效。

17.2 JMM个人理解

线程之间的共享变量存储在主内存中(Main Memory)中,每个线程都一个都有一个私有的本地内存(Local Memory),本地内存中存储了该线程以读/写共享变量的副本。

在这里插入图片描述

17.3 Volatile与Synchronized比较

  1. Volatile是轻量级的synchronized,因为它不会引起上下文的切换和调度,所以Volatile性能更好
  2. Volatile只能修饰变量,synchronized可以修饰方法,静态方法,代码块
  3. Volatile对任意单个变量的读/写具有原子性,但是类似于i++这种复合操作不具有原子性。而锁的互斥执行的特性可以确保对整个临界区代码执行具有原子性
  4. 多线程访问volatile不会发生阻塞,而synchronized会发生阻塞
  5. volatile是变量在多线程之间的可见性,synchronize是多线程之间访问资源的同步性

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

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

相关文章

Opencv项目实战:19 手势控制鼠标

目录 0、项目介绍 1、效果展示 2、项目搭建 3、项目代码展示 HandTrackingModule.py VirtualMouse.py 4、项目资源 5、项目总结 0、项目介绍 在Opencv项目实战&#xff1a;15 手势缩放图片中&#xff0c;我们搭建了HandTrackingModule模块&#xff0c;但在这里你还得用…

离散数学与组合数学-04图论上

文章目录离散数学与组合数学-04图论上4.1 图的引入4.1.1 图的示例4.1.2 无序对和无序积4.1.3 图的定义4.2 图的表示4.2.1 集合表示和图形表示4.2.2 矩阵表示法4.2.3 邻接点与邻接边4.3 图的分类4.3.1 按边的方向分类4.3.2 按平行边分类4.3.3 按权值分类4.3.4 综合分类方法4.4 图…

MySQL —— 表操作

目录 一、创建表 二、创建表的案例 三、查看表的结构 四、修改表 五、删除表 一、创建表 语法&#xff1a; CREATE TABLE [IF NOT EXISTS] table_name(field1 datatype1 [COMMENT 注释信息],field2 datatype2 [COMMENT 注释信息],field3 datatype3 [COMMENT 注释信息] )…

通信原理简明教程 | 模拟信号的数字化传输

文章目录1 抽样及抽样定理1.1 抽样1.2 抽样定理2 量化及量化信噪比2.1 均匀量化2.2 量化误差和量化信噪比2.3 非均匀量化3 编 码3.1常用的二进制码组3.2 均匀量化编码方法3.3 A律13折线编码4 脉冲编码调制系统4.1 PCM系统的码元速率4.2 PCM系统的抗噪声性能5 预测编码5.1 差分脉…

【Kotlin】扩展函数 ③ ( 定义扩展文件 | 重命名扩展函数 | Kotlin 标准库扩展函数 )

文章目录一、定义扩展文件二、重命名扩展函数三、Kotlin 标准库扩展函数一、定义扩展文件 如果定义的 扩展函数 需要在 多个 Kotlin 代码文件 中使用 , 则需要在 单独的 Kotlin 文件 中定义 , 该文件被称为 扩展文件 ; 定义 标准库函数 的 Standard.kt 就是 独立的 扩展文件 ;…

IDEA搭建Finchley.SR2版本的SpringCloud父子基础项目-------Feign负载均衡

1.概述 官网&#xff1a;http://projects.spring.io/spring-cloud/spring-cloud.html#spring-cloud-feign Feign是一个声明式WebService客户端。使用Feign能让编写Web Service客户端更加简单, 它的使用方法是定义一个接口&#xff0c;然后在上面添加注解&#xff0c;同时也支…

[Linux]进程地址空间

&#x1f941;作者&#xff1a; 华丞臧. &#x1f4d5;​​​​专栏&#xff1a;【LINUX】 各位读者老爷如果觉得博主写的不错&#xff0c;请诸位多多支持(点赞收藏关注)。如果有错误的地方&#xff0c;欢迎在评论区指出。 推荐一款刷题网站 &#x1f449; LeetCode刷题网站 文…

谁你的财神 谁是你的穷神

送穷神&#xff0c;迎灶神&#xff0c;下午提前准备迎接财神 我们说一个人穷&#xff0c;揭不开锅了&#xff0c;只能喝凉水了&#xff0c;到后来只能喝西北风 谁是我们的财神&#xff0c;信任我们的人&#xff0c;帮助我们的人&#xff0c;感谢过往贵人的资助 但是信任是不对…

【数据结构】算法复杂度

文章目录引入算法复杂度一.时间复杂度定义大O渐进表示法经典例题常量字符串二分查找冒泡排序递归1.阶乘2.斐波切纳数列二.空间复杂度定义经典例题冒泡排序递归1.阶乘2.斐波切纳数列引入 为什么要有算法复杂度&#xff1f; 当我们正在解决一个问题的时候&#xff0c;想出了多种思…

【计算机基础】操作系统

前言&#xff1a;本文适合用于基础了解和背诵&#xff0c;尽可能采用流畅且简短的语言回答操作系统相关问题并且辅以图片帮助记忆&#xff0c;不适合用作详细了解与深入学习 。 总述 操作系统部分主要分为以下几个重点 —— 操作系统基础 、 进程和线程、操作系统的内存管理、…

JAVA基础知识07常用API

目录 1. 常用API 1.1 简介 1.2 String类 1.2.1 字符串在开发中的应用场景 1.2.2 String 类的特点 1.2.3 String 类的常见构造方法 1.2.4 String 类的常见面试题 1.2.5 面试题题解 1.2.6 String 类用于比较的方法 1.2.7 String 字符串的遍历 1.2.8 String 字符串的截取…

QByteArray字节流和二进制与字符的关系以及tohex() toLatin1

QByteArray 存储的是字节&#xff0c;二进制形式&#xff0c;即ascii码的二进制编码。输出的时候&#xff0c;会输出二进制对应的字符 即一个映射: 二进制到ascii码的映射而.tohex()会将二进制转化为16进制字符&#xff0c;这里的16进制字符又是作为值域了&#xff0c;实际存…

JavaEE-文件和IO(二)

目录2.2 文件内容相关的操作三、文件操作案例3.1 案例一3.2 案例二3.3 案例三2.2 文件内容相关的操作 打开文件读文件写文件关闭文件 针对文件内容的读写&#xff0c;java标准库提供了一组类~ 首先按照文件的内容&#xff0c;分为两个系列 字节流对象&#xff0c;针对二进制…

手把手教你写web全栈入门项目—React+Koa+MongoDB(3w字教程,真的很详细,有代码)

手把手教你写web全栈入门项目—ReactKoaMongoDB 文章目录手把手教你写web全栈入门项目—ReactKoaMongoDB前言一、推荐基础二、所需环境三、软件四、项目源码五、文章结构六、遇到问题怎么办前端一、页面登录页首页二、目录结构三、技术选择四、开始项目1、页面组件1.1 目录1.2 …

JavaScript 所见所得文本编辑器 Froala Editor 4.0.17Crack

Froala Editor v4.0.17 清除格式工具现在可以从粘贴的内容中删除内联样式。 2023 年 1 月 24 日 - 9:07新版本 特征 清除格式工具现在可以从粘贴的内容中删除内联样式。 改进的“删除时保留格式”功能可保留已删除文本的格式并将其应用于替换文本。 选择图像时&#xff0c;用于…

day20|77. 组合。回溯的开始

回溯思路 void backtracking(参数) {if (终止条件) {存放结果;return;}for (选择&#xff1a;本层集合中元素&#xff08;树中节点孩子的数量就是集合的大小&#xff09;) {处理节点;backtracking(路径&#xff0c;选择列表); // 递归回溯&#xff0c;撤销处理结果} } 77. 组合…

91.使用注意力机制的seq2seq以及代码实现

1. 动机 2. 加入注意力 key和value是一样的 假设英语句子长为3的话&#xff0c;就会有3个key-value pair&#xff0c;key和vlaue是一个东西&#xff0c;每一个key-value pair对应第i个词的RNN的输出。之前的seq2seq只使用了最后的key-value&#xff0c;现在则是把所有的key-val…

JavaWeb语法八:网络原理初识

目录 1.局域网与广域网 1.1&#xff1a;局域网 1.2&#xff1a;广域网 2&#xff1a;网络基础知识 3.协议分层 3.1&#xff1a;分层的好处 3.2&#xff1a;TCP/IP五层&#xff08;或四层&#xff09;模式 4&#xff1a;封装和分用 4.1&#xff1a;封装 4.2&#xff1…

MyBatisPlus入门简介

目录 1. 入门案例 问题导入 1.1 SpringBoot整合MyBatisPlus入门程序 2. MyBatisPlus概述 问题导入 2.1 MyBatis介绍​​​​​​​ 1. 入门案例 问题导入 MyBatisPlus环境搭建的步骤&#xff1f; 1.1 SpringBoot整合MyBatisPlus入门程序 ①&#xff1a;创建新模块&am…

P3368 【模板】树状数组 2

【模板】树状数组 2 题目描述 如题&#xff0c;已知一个数列&#xff0c;你需要进行下面两种操作&#xff1a; 将某区间每一个数加上 xxx&#xff1b; 求出某一个数的值。 输入格式 第一行包含两个整数 NNN、MMM&#xff0c;分别表示该数列数字的个数和操作的总个数。 第…