一、Java内存模型(JMM)

        JMM(Java Memory Model,Java 内存模型)是 Java 虚拟机规范中定义的一种抽象概念,用于规范 Java 程序中多线程对共享内存的访问规则,解决可见性、原子性和有序性问题,确保 Java 程序在不同硬件和操作系统上都能获得一致的并发行为。

运行时数据区划分

        线程私有:程序计数器、本地方法栈、虚拟机栈

        线程公有:堆、元空间

程序计数器

        字节码解释器在解释执行字节码文件工作时,当需要需要执行一条字节码指令时,可以通过改变程序计数器的值来完成。

虚拟机栈

        虚拟机栈是由一个个栈帧组成,而每个栈帧中都有:局部变量、操作数栈、动态链接、方法出口信息。每个方法调用时都会入栈,每个方法被调用结束后则会出栈,这样可以清楚的看出方法之间的调用关系。

本地方法栈

        native关键字修饰的本地方法被执行时候,在本地方法栈中创建一个栈帧,用于存放发native本地方法的局部变量、操作数栈、动态链接、方法出口信息。方法执行完毕后,栈帧会释放空间。

堆(Heap)

        用于存放对象实例和数组的内存区域。

1、新生代、老年代

        由于垃圾回收的需要,避免频繁GC所以将堆分为新生代和老年代,其中新生代占1/3,老年代占2/3。而新生代又被分为EdenSurvivor区(from、to),占比为8:1:1。

2、对象创建时的内存分配

        当创建一个新对象时会先看Eden区有没有空间进行存储,若没有则执行YGC,执行后若还不能放下则看老年区是否可以放下,如果老年区不能放下,则执行老年区的FGC,执行后如果还不能不能放下,则会抛出OOM异常。

二、GC垃圾回收器

判读对象是否存活

1、引用计数算法

        在对象中添加一个引用计数器,如果对象被引用则+1,如果失去引用则-1,当我们需要判断对象是否存活时,只需看该计算器的值是否为0。该方法不用于java中。

        缺点:可能会出现循环引用的情况,从而出现死锁。也就是a引用了b,b也引用了a。

2、可达性分析算法

        通过定义一系列的" GC Roots "的根结点来作为开始结点集,当需要判断对象是否存活时,则从根结点向下遍历,没有被遍历到的则是可以被回收的垃圾对象。该方法用于java中。

3、java中四种引用类型

  • 强引用

        最常见的引用类型,直接通过 new 关键字创建的对象引用。

// 强引用
Object object = new Object();

        强引用它永远不会被GC回收,当我们需要他被回收时,我们可以对其进行弱化。

// 弱化
object = null;
  • 软引用

        该引用类型可以根据内存的大小来判断是否进行GC回收,当内存充足时不进行回收,当内存不足时进行回收。

// 软引用
SoftReference<Object> softRef = new SoftReference<>(new Object());
Object obj = softRef.get();  // 获取软引用指向的对象
  • 弱引用

         该引用类型无论是否内存充足只要发生GC就会被回收。例如:ThreadLocal中应用了弱引用

如果不使用对象后没有及时进行销毁,当发生GC时就会出现大量的null-value的键值对,从而导致发生OOM。

// 弱引用
WeakReference<Object> weakRef = new WeakReference<>(new Object());
Object obj = weakRef.get();  // 获取弱引用指向的对象
  • 虚引用

        虚引用主要用来跟踪对象被垃圾回收的活动,可以在垃圾收集时收到一个系统通知。

// 虚引用
ReferenceQueue<Object> queue = new ReferenceQueue<>();
PhantomReference<Object> phantomRef = new PhantomReference<>(new Object(), queue);

垃圾回收算法


复制算法

        将内存空间划分为 两个相等的区域(如 From 空间和 To 空间),每次只使用其中一个区域:

  1. 当该区域内存用完时,将存活对象复制到另一个区域。
  2. 清空原区域的所有内存,完成垃圾回收。

缺点

  • 内存利用率低:需要预留一半内存空间,实际可用内存仅为总空间的 50%。
  • 当存活对象较多时,复制成本高。

标记---清除算法

主要分两个阶段进行:

  1. 标记阶段:从根对象(如栈变量、静态变量)出发,遍历所有可达对象,并标记为 “存活”。
  2. 清除阶段:扫描整个堆内存,将未被标记的对象(即垃圾)回收,并释放其占用的内存空间。

缺点

  • 内存碎片化:回收后会产生大量不连续的内存碎片,可能导致后续无法分配大对象。
  • 效率较低:需要遍历两次内存(标记和清除)。

标记---整理算法

主要分两个阶段进行:

  1. 标记阶段:同标记 - 清除算法,标记所有存活对象。
  2. 整理阶段:将所有存活对象向内存一端移动,然后直接清理边界外的所有内存(即垃圾对象占用的空间)。

缺点

  • 性能开销大:需要移动对象,涉及内存复制,成本较高。

总结:由于不同算法的逻辑有所不同,所以他们的用处也有所不同。由于在新生代中的对象总是朝生夕灭,所以通常我们会使用复制算法进行垃圾回收;而老年代中的对象可以长期存活,所以我们通常适用标记---整理和标记清除算法。

 

垃圾收集器

Serial收集器(新生代)

       该收集器主要对新生代的垃圾进行收集清理,采用" 复制 "算法进行实现。

Serial Old收集器(老年代)

        该收集器主要对老年代的垃圾进行收集清理,采用" 标记---整理 "算法进行实现。

        他们两个是串行收集器,也可以理解为单线程收集器,但在进行GC时会发生STW所以现在一般不使用。


Parallel Scavenge收集器(新生代)

        该收集器主要对新生代的垃圾进行收集清理,采用" 复制 "算法进行实现。

Parallel Old收集器(老年代)

        该收集器主要对老年代的垃圾进行收集清理,采用" 标记---整理 "算法进行实现。

        他们两个是多线程收集器,但在进行GC时会发生STW,但相对于前面性能会好很多。但是该收集器主要强调系统的吞吐量,所以会很容易出现系统上线后,内存占用过高的情况。


CMS收集器(老年代)

        该收集器是一个基于" 标记---清除 "算法实现,是一种获取最短回收停顿(STW)为目标的收集器,它可以实现让收集线程和用户线程并发。

        CMS 的执行过程分为四个主要阶段:

  1. 初始标记(Initial Mark, STW):通过 GC Roots 标记直接关联到根对象的存活对象。

  2. 并发标记(Concurrent Mark):与应用线程并发执行,遍历所有可达对象并标记存活对象。

  3. 重新标记(Remark, STW):修正并发标记期间因应用线程修改引用导致的标记错误。

  4. 并发清除(Concurrent Sweep)特点:无需暂停,但可能产生 “浮动垃圾”(即在清除阶段新产生的垃圾,需等到下一次 GC 处理)。

        由于该 标记---清除 算法所以会产生大量的内存空间碎片导致,空间的浪费;而且在并发清除的时候可能会产生浮动垃圾


G1收集器(老年代)

        该搜集器主要针对大内存的机器,它采用局部性的收集思想将一块大内存划分为若干大小相同的独立区域(Region),再讲这些独立的区域收集成一个回收集合,再进行处理。

G1 的垃圾回收周期主要分为以下阶段:

  1. 初始标记(Initial Mark, STW):通过 GC Roots 标记直接关联到根对象的存活对象。

  2. 并发标记(Concurrent Marking):与应用线程并发执行,遍历所有可达对象并标记存活对象。

  3. 最终标记(Final Mark, STW):处理并发标记期间的引用变化(即未被标记的新对象),完成标记过程。

  4. 筛选回收(Cleanup and Evacuation, STW):根据 Region 的回收价值(垃圾占比)排序,选择部分 Region 进行回收。

 

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

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

相关文章

二叉树算法之【二叉树的层序遍历】

目录 LeetCode-102题 LeetCode-102题 给定二叉树的根节点root&#xff0c;返回其节点值的层序遍历&#xff08;即逐层地&#xff0c;从左到右访问所有节点&#xff09;。 class Solution {public List<List<Integer>> levelOrder(TreeNode root) {// checkif (r…

uniapp+vue3——通知栏标题纵向滚动切换

介绍 取巧&#xff0c;使用纵向轮播实现 <!-- 通知栏 --> <view class"noticeBox" v-if"notice.length>0"><image src"/static/images/index/noticeIcon.png" mode"aspectFill"></image><swiper class&…

BilldDesk 开源、免费、吊打收费软件!白嫖党最爱!远程控制神器,没有任何连接次数和画质限制,同时显示多屏、屏幕墙等高级功能

远程控制软件哪个好用&#xff1f;TeamViewer收费太贵&#xff0c;向日葵限制太多&#xff0c;QQ远程又不稳定……别担心&#xff01;今天给大家推荐一款完全免费、开源的远程控制神器——BilldDesk&#xff01;它不仅功能强大&#xff0c;而且支持Windows、macOS、Linux、Andr…

ios UIAppearance 协议

一、前言 iOS 上提供了一个比较强大的工具UIAppearance&#xff0c;我们通过UIAppearance设置一些UI的全局效果&#xff0c;这样就可以很方便的实现UI的自定义效果又能最简单的实现统一界面风格。 (id)appearance ; 这个是这个协议里最重要的方法了 . 这个方法是统一全部改&am…

进阶数据结构:用红黑树实现封装map和set

​ 嘿,各位技术潮人!好久不见甚是想念。生活就像一场奇妙冒险,而编程就是那把超酷的万能钥匙。此刻,阳光洒在键盘上,灵感在指尖跳跃,让我们抛开一切束缚,给平淡日子加点料,注入满满的 passion。准备好和我一起冲进代码的奇幻宇宙了吗?Let’s go! 我的博客:yuanManGa…

【数据结构初阶】--二叉树(五)

&#x1f525;个人主页&#xff1a;草莓熊Lotso &#x1f3ac;作者简介&#xff1a;C研发方向学习者 &#x1f4d6;个人专栏&#xff1a; 《C语言》 《数据结构与算法》《C语言刷题集》《Leetcode刷题指南》 ⭐️人生格言&#xff1a;生活是默默的坚持&#xff0c;毅力是永久的…

redis布隆过滤器解决缓存击穿问题

在电商系统中&#xff0c;商品详情页是一个典型的高频访问场景。当用户请求某个商品的详情时&#xff0c;系统会优先从缓存中获取数据。如果缓存中没有该商品的详情&#xff0c;系统会去数据库查询并更新缓存。然而&#xff0c;如果某个热门商品的缓存失效&#xff0c;大量请求…

1+1>2!特征融合如何让目标检测更懂 “场景”?

来gongzhonghao【图灵学术计算机论文辅导】&#xff0c;快速拿捏更多计算机SCI/CCF发文资讯&#xff5e;在多模态大模型&#xff08;MLLM&#xff09;时代&#xff0c;特征融合与目标检测的研究方向正变得愈发关键。从红外与可见光图像的融合&#xff0c;到语音活动检测中的特征…

详解赛灵思SRIO IP并提供一种FIFO封装SRIO的收发控制器仿真验证

概述RapidIO标准定义为三层&#xff1a;逻辑层、传输层、物理层。逻辑层&#xff1a;定义总体协议和包格式&#xff0c;包含设备发起/完成事务的必要信息。传输层&#xff1a;提供包传输的路由信息&#xff08;对顶层不可见&#xff09;。物理层&#xff1a;描述设备级接口细节…

深度学习:简介与任务分类总览

一、什么是深度学习&#xff1f;1.1 深度学习的定义深度学习&#xff08;Deep Learning&#xff09;是机器学习的一种特殊形式&#xff0c;它依赖于具有多层结构的神经网络自动从数据中学习特征并完成任务&#xff0c;如图像识别&#xff0c;语音识别&#xff0c;自然语言处理等…

MSPM0开发学习笔记:二维云台画图(2025电赛 附源代码及引脚配置)

前言 今年的电赛&#xff08;2025&#xff09;&#xff0c;很多题都与云台相关&#xff0c;因此为备战电赛&#xff0c;博主这边也是准备了一个由两个42步进电机驱动的云台并提前进行调试&#xff0c;避免赛题出来之后手忙脚乱的&#xff0c;这边的两个42步进电机采用同一个驱…

借助 Wisdom SSH 的 AI 助手构建 Linux 开发环境

借助Wisdom SSH的AI助手构建Linux开发环境 在Linux系统的开发场景中&#xff0c;快速、准确地搭建开发环境至关重要。Wisdom SSH凭借其强大的AI助手&#xff0c;能极大简化这一过程&#xff0c;其官网为ssh.wisdomheart.cn。以下以在Ubuntu 22.04服务器上构建Python开发环境&am…

Python 程序设计讲义(44):组合数据类型——集合类型:创建集合

Python 程序设计讲义&#xff08;44&#xff09;&#xff1a;组合数据类型——集合类型&#xff1a;创建集合 目录Python 程序设计讲义&#xff08;44&#xff09;&#xff1a;组合数据类型——集合类型&#xff1a;创建集合一、集合的特征二、创建集合&#xff1a;使用set()函…

10 - 大语言模型 —Transformer 搭骨架,BERT 装 “双筒镜”|解密双向理解的核心

目录 1、为什么 BERT 能 “懂” 语言&#xff1f;先看它的 “出身” 2、核心逻辑 2.1、“自学阶段”—— 预训练&#xff0c;像婴儿学说话一样积累语感 2.1.1、简述 2.1.2、核心本事&#xff1a;“双向注意力”&#xff0c;像人一样 “聚焦重点” 2.2、“专项复习”—— …

【Spring Boot 快速入门】四、MyBatis

目录MyBatis&#xff08;一&#xff09;入门简介MyBatis 入门LombokMyBatis 基础操作数据准备删除预编译新增更新查询XML 映射文件MyBatis&#xff08;一&#xff09;入门 简介 MyBatis 是一款 优秀的持久层框架&#xff0c;它支持 自定义 SQL、存储过程以及高级映射&#xf…

Spring IOC 基于Cglib实现含构造函数的类实例化策略

作者&#xff1a;小凯 分享、让自己和他人都能有所收获&#xff01; 一、前言 技术成长&#xff0c;是对场景设计细节不断的雕刻&#xff01; 你觉得自己的技术什么时候得到了快速的提高&#xff0c;是CRUD写的多了以后吗&#xff1f;想都不要想&#xff0c;绝对不可能&#xf…

composer 常用命令

### 设置镜像源全局设置composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/当个项目设置composer config repo.packagist composer https://mirrors.aliyun.com/composer/恢复官方源composer config -g --unset repos.packagist### 常用源阿里云…

【python】Python爬虫入门教程:使用requests库

Python爬虫入门教程&#xff1a;使用requests库 爬虫是数据获取的重要手段&#xff0c;下面我将通过一个完整的示例&#xff0c;教你如何使用Python的requests库编写一个简单的爬虫。我们将以爬取豆瓣电影Top250为例。 【python】网络爬虫教程 - 教你用python爬取豆瓣电影 Top…

OpenCV图像缩放:resize

图像缩放是图像处理中的基础操作之一。无论是图像预处理、数据增强还是图像金字塔构建&#xff0c;cv::resize 都是我们最常用的函数之一。但你是否注意到&#xff0c;在 OpenCV 中同时还存在一个名为 cv::Mat::resize 的方法&#xff1f;这两个函数虽然名字类似&#xff0c;但…

汽车、航空航天、适用工业虚拟装配解决方案

一、现状在制造业数字化转型浪潮中&#xff0c;传统装配过程仍面临诸多挑战&#xff1a;物理样机试错成本高、装配周期冗长、工艺优化依赖经验、跨部门协作效率低下……如何打破“试错-返工”的恶性循环&#xff1f;目前总装工艺通过DELMIA、NX、Creo等工程软件进行工艺装配验证…