Java垃圾收集器与内存分配策略深度解析
在 Java 与 C++ 的世界里,内存动态分配与垃圾收集技术仿佛筑起了一道高墙。墙外的人渴望进入,享受自动内存管理的便利;而墙内的人却试图突破,追求更高的性能与控制力。今天,就让我们深入探讨 Java 的垃圾收集器与内存分配策略,一窥其背后的奥秘。
3.1 概述
垃圾收集(Garbage Collection,简称 GC)并非 Java 的专属产物。早在 1960 年,Lisp 语言就率先引入了内存动态分配与垃圾收集技术。当时,Lisp 的设计者 John McCarthy 就明确了垃圾收集需要解决的三大问题:哪些内存需要回收?何时回收?如何回收?
经过半个多世纪的发展,内存动态分配与回收技术已相当成熟。然而,当系统面临内存溢出、内存泄漏问题,或者垃圾收集成为性能瓶颈时,开发者仍需深入了解这些“自动化”技术的细节,以便进行有效的监控与优化。
在 Java 中,程序计数器、虚拟机栈、本地方法栈等区域的内存分配与回收具有确定性,随线程的生命周期而自然回收。而 Java 堆和方法区则截然不同,它们的内存分配与回收具有高度不确定性,这也是垃圾收集器重点关注的区域。
3.2 对象已死?
在 Java 堆中,垃圾收集器的核心任务是区分存活对象与死亡对象。那么,如何判断一个对象是否存活呢?
3.2.1 引用计数算法
引用计数算法是一种简单直观的判断方法。它为每个对象设置一个引用计数器,每当有引用指向该对象时,计数器加一;当引用失效时,计数器减一。当计数器为零时,表示该对象不再被使用,可以被回收。
然而,引用计数算法存在明显的缺陷。它无法解决对象之间的循环引用问题。例如,两个对象互相引用,即使它们已经无法被外部访问,它们的引用计数也永远不会为零,从而导致内存泄漏。
3.2.2 可达性分析算法
当前主流的编程语言(如 Java、C# 等)都采用可达性分析算法来判断对象是否存活。该算法从一组称为“GC Roots”的根对象出发,沿着引用链向下搜索。如果一个对象到 GC Roots 之间没有任何引用链相连,则该对象被认为是不可达的,可以被回收。
在 Java 中,以下对象可以作为 GC Roots:
-
虚拟机栈(栈帧中的本地变量表)中引用的对象。
-
方法区中类静态属性引用的对象。
-
方法区中常量引用的对象。
-
本地方法栈中 JNI 引用的对象。
-
Java 虚拟机内部的引用,如基本数据类型对应的 Class 对象、常驻异常对象等。
-
所有被同步锁持有的对象。
-
反映 Java 虚拟机内部情况的 JMX Bean、JVMTI 中注册的回调、本地代码缓存等。
3.2.3 再谈引用
从 JDK 1.2 开始,Java 对引用的概念进行了扩充,将引用分为强引用、软引用、弱引用和虚引用四种,分别对应不同的内存回收策略。
-
强引用:最传统的引用形式,如
Object obj = new Object()
。只要强引用存在,垃圾收集器永远不会回收被引用的对象。 -
软引用:用于描述一些有用但非必须的对象。当内存不足时,垃圾收集器会回收这些对象。适用于缓存场景。
-
弱引用:比软引用更弱,被弱引用关联的对象只会在下一次垃圾收集时被回收。适用于监听器等场景。
-
虚引用:最弱的引用形式,无法通过虚引用来获取对象实例。主要用于在对象被回收时接收通知。
3.2.4 生存还是死亡?
即使对象在可达性分析中被判定为不可达,也不一定会被立即回收。如果对象覆盖了 finalize()
方法,并且该方法尚未被虚拟机调用过,那么该对象会被放入 F-Queue 队列中,由 Finalizer 线程执行其 finalize()
方法。如果对象在 finalize()
方法中重新与引用链上的某个对象建立关联,那么它将被移出回收队列;否则,它将被回收。
需要注意的是,finalize()
方法的执行代价高昂,且存在不确定性。它并不等同于 C++ 中的析构函数,也不建议用于关闭外部资源等清理工作。现代 Java 开发中,应尽量避免使用 finalize()
方法。
3.2.5 回收方法区
方法区(如 HotSpot 虚拟机中的元空间或永久代)也可能进行垃圾收集,主要回收废弃的常量和不再使用的类。回收废弃常量相对简单,而判定一个类是否可以被回收则需要满足以下三个条件:
-
该类的所有实例都已被回收。
-
加载该类的类加载器已被回收。
-
该类对应的
java.lang.Class
对象没有被引用。
HotSpot 虚拟机提供了 -XX:+PrintClassHistogram
参数用于查看类的加载情况,以及 -XX:+TraceClassLoading
和 -XX:+TraceClassUnloading
参数用于跟踪类的加载与卸载。
3.3 垃圾收集算法
垃圾收集算法主要分为两大类:引用计数式垃圾收集和追踪式垃圾收集。由于引用计数式垃圾收集在主流 Java 虚拟机中未被采用,本文主要介绍追踪式垃圾收集算法及其相关理论。
3.3.1 分代收集理论
分代收集理论是现代垃圾收集器的核心设计思想。它基于以下两个分代假说:
-
弱分代假说:绝大多数对象都是朝生夕灭的。
-
强分代假说:熬过越多次垃圾收集过程的对象就越难以消亡。
根据这两个假说,Java 堆被划分为新生代和老年代。新生代主要存储新创建的对象,这些对象通常具有较短的生命周期;老年代则存储经过多次垃圾收集后仍然存活的对象。
分代收集理论还引入了跨代引用假说:跨代引用相对于同代引用来说只占极少数。基于这一假说,垃圾收集器在进行新生代收集时,只需关注老年代中存在跨代引用的区域,而无需扫描整个老年代。这一机制通过“记忆集”(Remembered Set)实现。
3.3.2 标记-清除算法
标记-清除算法是最基础的垃圾收集算法,由 John McCarthy 在 1960 年提出。它分为“标记”和“清除”两个阶段:首先标记出所有需要回收的对象,然后统一回收这些对象。
标记-清除算法的主要缺点是执行效率不稳定,且容易产生内存碎片。当堆中对象数量较多时,标记和清除过程的开销会显著增加。此外,标记-清除算法可能导致内存碎片化,影响后续大对象的分配。
3.3.3 标记-复制算法
标记-复制算法通过将内存划分为两块区域,每次只使用其中一块,当内存用完时,将存活对象复制到另一块区域,然后清理已使用过的内存。这种算法的优点是实现简单,运行高效,但缺点是会浪费一半的内存空间。
现代 Java 虚拟机(如 HotSpot)通常采用一种改进的标记-复制算法,称为“Appel 式回收”。它将新生代划分为一个较大的 Eden 空间和两个较小的 Survivor 空间。每次分配内存时,只使用 Eden 和其中一个 Survivor 空间。垃圾收集时,将 Eden 和 Survivor 中的存活对象复制到另一个 Survivor 空间,然后清理 Eden 和已使用的 Survivor 空间。
3.3.4 标记-整理算法
标记-整理算法主要用于老年代的垃圾收集。它在标记阶段与标记-清除算法相同,但在后续步骤中,将所有存活对象向内存空间一端移动,然后清理边界以外的内存。这种算法的优点是可以避免内存碎片化问题,但缺点是移动对象和更新引用的开销较大。
3.4 HotSpot 的算法细节实现
3.4.1 根节点枚举
根节点枚举是垃圾收集过程中的关键步骤。HotSpot 虚拟机通过 OopMap 数据结构快速准确地完成 GC Roots 枚举。OopMap 记录了对象内每个偏移量上数据的类型,以及栈和寄存器中引用的位置。这样,垃圾收集器在扫描时可以直接获取这些信息,而无需从头开始查找。
3.4.2 安全点
安全点是 HotSpot 虚拟机中用于暂停用户线程的机制。由于生成 OopMap 的成本较高,HotSpot 并非为每条指令都生成 OopMap,而是在特定位置记录这些信息,这些位置被称为安全点。当垃圾收集发生时,用户线程会运行到最近的安全点并暂停。
HotSpot 使用主动式中断机制,通过设置标志位让线程在安全点上主动中断挂起。轮询标志的操作被优化为一条汇编指令,以提高效率。
3.4.3 安全区域
安全区域用于解决线程处于 Sleep 或 Blocked 状态时无法响应垃圾收集的问题。线程进入安全区域时会标识自己,垃圾收集器在回收时可以忽略这些线程。线程离开安全区域时,会检查垃圾收集是否完成,若未完成则等待。
3.4.4 记忆集与卡表
记忆集用于记录从非收集区域指向收集区域的指针集合,以避免扫描整个老年代。卡表是记忆集的一种常见实现形式,通过字节数组记录卡页的状态。HotSpot 虚拟机中,卡表的每个元素对应一个卡页,卡页大小为 512 字节。当卡页内存在跨代引用时,对应的卡表元素会被标记为“脏”。
3.4.5 写屏障
写屏障用于维护卡表的状态。HotSpot 虚拟机通过写屏障技术,在引用类型字段赋值时更新卡表。写屏障分为写前屏障和写后屏障,HotSpot 主要使用写后屏障。
3.4.6 并发的可达性分析
并发的可达性分析是现代垃圾收集器的关键技术之一。它允许垃圾收集器与用户线程并发执行,从而减少停顿时间。HotSpot 虚拟机通过三色标记算法和写屏障技术实现并发可达性分析。
三色标记算法将对象分为白色、灰色和黑色三种状态,分别表示尚未访问、已访问但引用未扫描、已完全扫描。并发执行时,可能会出现“对象消失”问题,即原本存活的对象被误标为已消亡。为解决这一问题,HotSpot 虚拟机采用了增量更新和原始快照两种解决方案。
相关文章:
Java垃圾收集器与内存分配策略深度解析
在 Java 与 C 的世界里,内存动态分配与垃圾收集技术仿佛筑起了一道高墙。墙外的人渴望进入,享受自动内存管理的便利;而墙内的人却试图突破,追求更高的性能与控制力。今天,就让我们深入探讨 Java 的垃圾收集器与内存分配…...
优化MySQL性能:主从复制与读写分离实践指南
目录 一、知识介绍 1.MySQL主从复制原理 2.MySQL读写分离原理 二、资源清单 三、案例实施 1.修改主机名 2.搭建MySQL主从复制 3.搭建MySQL读写分离 一、知识介绍 1.MySQL主从复制原理 MySQL支持的复制类型 基于语句的复制基于行的复制混合模型复制 工作过程 主&#…...
Foupk3systemX5OS系统产品设备
Foupk3systemX5OS TXW8(基于Foupk3systemX5OS系统19.62正式版开发的智能移动设备由Foupk3systemX5OS系统与FOUPK3云服务平台共同自主研发) Foupk3systemX5OS TX6(Foupk3systemX5OS TX6基于Foupk3systemX5OS系统19.60正式版开发的智能平板设备…...
【计网】认识跨域,及其在go中通过注册CORS中间件解决跨域方案,go-zero、gin
一、跨域(CORS)是什么? 跨域,指的是浏览器出于安全限制,前端页面在访问不同源(协议、域名、端口任一不同)的后端接口时,会被浏览器拦截。 比如: 前端地址后端接口地址是…...
关于 【Spring Boot Configuration Annotation Processor 未配置问题】 的详细分析、解决方案及代码示例
以下是关于 Spring Boot Configuration Annotation Processor 未配置问题 的详细分析、解决方案及代码示例: 1. 问题描述 当使用 Spring Boot 的配置注解(如 ConfigurationProperties、Value、ConditionalOnProperty 等)时,若未…...
MySQL 的ANALYZE与 OPTIMIZE命令
MySQL 的ANALYZE与 OPTIMIZE命令 一、ANALYZE TABLE - 更新统计信息 1. 基本语法与功能 ANALYZE [NO_WRITE_TO_BINLOG | LOCAL] TABLE tbl_name [, tbl_name] ...作用:收集表统计信息用于优化器生成更优的执行计划,主要更新: 索引基数&am…...
【机器学习】人工智能在电力电子领域的应用
摘要: 本文概述了电力电子系统的人工智能 (AI) 应用。设计、控制和维护这三个独特的生命周期阶段与人工智能要解决的一项或多项任务相关,包括优化、分类、回归和数据结构探索。讨论了专家系统、模糊逻辑、元启发法和机器学习四类人工智能的应用。我们对…...
InferType和_checked_type的区别?
在 TVM 的 Relay IR 中,relay.frontend.common.infer_shape(node) 和 node.checked_type.shape 都与**形状(Shape)**信息相关,但它们的用途、实现机制和性能特点有显著区别。以下是详细对比: 1. 功能区别 特性node.ch…...
Flutter 学习之旅 之 flutter 作为 module ,在 Android 端主动唤起 Flutter 开发的界面 简单的整理
Flutter 学习之旅 之 flutter 作为 module ,在 Android 端主动唤起 Flutter 开发的界面 简单的整理 目录 Flutter 学习之旅 之 flutter 作为 module ,在 Android 端主动唤起 Flutter 开发的界面 简单的整理 一、简单介绍 二、Android 端唤起 Flutter …...
vue3 css模拟语音通话不同语音、正在加载等的效果
实现效果如下: 在不同的时间,显示不一样的效果(大小是一样的,截图时尺寸发生了变化) 具体实现代码如下: <script setup> import {ref} from "vue";const max_hight ref(40px) const min…...
【Machine Learning Q and AI 读书笔记】- 01 嵌入、潜空间和表征
Machine Learning Q and AI 中文译名 大模型技术30讲,主要总结了大模型相关的技术要点,结合学术和工程化,对LLM从业者来说,是一份非常好的学习实践技术地图. 本文是Machine Learning Q and AI 读书笔记的第1篇,对应原…...
[Agent]AI Agent入门02——ReAct 基本理论与实战
ReAct介绍 ReAct(Reasoning and Acting)是一种通过协同推理(Reasoning)与行动(Acting)提升大语言模型(LLM)任务解决能力的技术。其核心思想是在解决复杂问题时交替生成推理和动作&a…...
uniapp自定义头部(兼容微信小程序(胶囊和状态栏),兼容h5)
很早之前就写过自定义头部,但是那时偷懒写死了,现在用插槽重新写了个 有两种形式: type1是完全自定义的,可以自己去组件改也可以用插槽改 type2是正常的返回标题和右边按钮,使用就是 title"标题" rightClic…...
mybatis的xml ${item}总是更新失败
场景 代码如下 void updateStatus(Param("deviceSerialIdCollection") Collection<String> deviceSerialIdCollection, Param("status") Integer status);<update id"updateStatus">UPDATE gb_monitor SET online#{status} WHERE d…...
数据库- JDBC
标题目录 JDBC基本概念JDBC 接口JDBC 工作原理 JDBC APIJDBC工作过程Driver 接口及驱动加载Connection 接口Statemen 接口ResultSet 接口PreparedStatement 接口 JDBC 基本概念 Java Database Connectivity:java访问数据库的解决方案希望用相同的方式访问不同的数…...
[26] cuda 应用之 nppi 实现图像格式转换
[26] cuda 应用之 nppi 实现图像格式转换 讲述 nppi 接口定义通过nppi实现 bayer 格式转rgb格式官网参考信息:http://gwmodel.whu.edu.cn/docs/CUDA/npp/group__image__color__debayer.html#details1. 接口定义 官网关于转换的原理是这么写的: Grayscale Color Filter Array …...
MYSQL-OCP官方课程学习截图
第一节 介绍...
医院信息管理系统全解析
目录 一、医院信息管理系统是什么 1. 概念阐释 2. 核心功能概述 二、医院信息管理系统的种类 1. 医院信息系统(HIS) 2. 电子病历系统(EMR) 3. 实验室信息管理系统(LIS) 三、医院信息管理系统的实际…...
模型上下文协议(MCP):技术解析与生态发展
一、概念与目标 模型上下文协议(Model Context Protocol,MCP)是由Anthropic于2024年11月推出的开源协议,旨在为大语言模型(LLM)与外部工具、数据源提供标准化的双向通信框架。其核心目标是打破数据孤岛&am…...
laravel中layui的table翻页不起作用问题的解决
本地测试是好的,部署的时候就发现,翻页不起作用了。但lay_num序号是可以变化的,查看api接口传递的数据,发现数据没有变化,加上page2等翻页,也是不起作用,看来是url参数返回给后台,后…...
python上测试neo4j库
安装完了neo4j库后,如何使用。用python来小试牛刀 1.从其他博客上找来demo #coding:utf-8 from py2neo import Graph,Node,Relationship##连接neo4j数据库,输入地址、用户名、密码 graph Graph(bolt://xx.xx.xx.xx:7687,userneo4j,passwordneo4j1234)…...
云原生周刊:Kubernetes v1.33 正式发布
开源项目推荐 Robusta Robusta 是一个开源的 K8s 可观测性与自动化平台,旨在增强 Prometheus 告警的智能化处理能力。它通过规则和 AI 技术对告警进行丰富化处理,自动附加相关的 Pod 日志、图表和可能的修复建议,支持智能分组、自动修复和高…...
网络安全入门综述
引言 在数字化时代,网络安全(Cybersecurity)已成为保护个人、企业和政府机构免受数字威胁的关键领域。随着互联网的普及、云计算的兴起以及物联网(IoT)设备的激增,网络攻击的频率和复杂性不断增加。从数据…...
LLaMA-Factory部署以及大模型的训练(细节+新手向)
LLaMA-Factory 经过一段时间的探索,从手动编写训练代码到寻求框架辅助训练,遇到了各种各样的问题。前面我介绍了dify的部署,但是并没有详细介绍使用方式,是因为我在尝试利用dify的时候碰到了很多困难,总结下来首先就是…...
ASP.NET MVC 入门指南四
21. 高级路由配置 21.1 自定义路由约束 除了使用默认的路由约束,你还可以创建自定义路由约束。自定义路由约束允许你根据特定的业务逻辑来决定一个路由是否匹配。例如,创建一个只允许特定年份的路由约束: csharp public class YearRouteCo…...
rabbitmq-集群部署
场景:单个pod,部署在主节点,基础版没有插件,进阶版多了一个插件 基础版本: --- apiVersion: v1 kind: PersistentVolume metadata:name: rabbitmq-pv spec:capacity:storage: 5GiaccessModes:- ReadWriteOncestorage…...
明远智睿SSD2351开发板:开启工业控制新征程
在工业控制领域,对开发板的性能、稳定性和扩展性有着极高的要求。明远智睿的SSD2351开发板凭借其卓越的特性,为工业控制带来了全新的解决方案。 SSD2351开发板搭载四核1.4GHz处理器,强大的运算能力使其在处理工业控制中的复杂任务时游刃有余。…...
RISCV学习(5)GD32VF103 MCU架构了解
RISCV学习(5)GD32VF103 MCU架构了解 1、芯片内核功能简介 GD32VF103 MCU架构,采用Bumblebee内核,芯来科技(Nuclei System Technology)与台湾晶心科技(Andes Technology)联合开发&am…...
IDEA2022.3开启热部署
1、开启IDEA的自动编译 1.1 具体步骤:打开顶部工具栏 File -> Settings -> Build,Execution,Deployment -> Compiler 然后勾选 Build project automatically 。 1.2 打开顶部工具栏 File -> Settings -> Advanced Settings -> Compiler -> 然…...
《算法吞噬幻想乡:GPT-4o引发的艺术平权运动与版权核爆》
一、引言:现象级AI艺术事件的社会回响 GPT - 4o吉卜力风格刷屏现象 在当今数字化浪潮中,GPT - 4o吉卜力风格的作品在网络上掀起了一阵刷屏热潮。吉卜力工作室以其独特的水彩质感、奇幻氛围和孤独美学,在全球范围内拥有大量粉丝。而GPT - 4o强…...
yolov5 源码 +jupyter notebook 笔记 kaggle
YOLOv5 | Kaggle 直接用的githuab的源码,git clone 后output才有文件 直接gitclone他的源码用Vscode看 好久没见过16g了 怎么这么便宜 https://gadgetversus.com/graphics-card/nvidia-tesla-p100-pcie-16gb-vs-nvidia-geforce-rtx-4060/#google_vignette 好的&am…...
聊天室系统:多任务版TCP服务端程序开发详细代码解释
1. 需求 目前我们开发的TCP服务端程序只能服务于一个客户端,如何开发一个多任务版的TCP服务端程序能够服务于多个客户端呢? 完成多任务,可以使用线程,比进程更加节省内存资源。 2. 具体实现步骤 编写一个TCP服务端程序,循环等…...
Python(15)迭代器和生成器
在 Python 编程领域中,迭代器和生成器是两个强大且独特的概念,它们为处理数据序列提供了高效且灵活的方式。这篇博客将结合菜鸟教程内容,通过丰富的代码示例,深入学习 Python3 中的迭代器与生成器知识,方便日后复习回顾…...
无刷空心杯电机及机器人灵巧手的技术解析与发展趋势
一、无刷空心杯电机结构与技术解析 1. 核心结构设计 无刷空心杯电机的核心设计突破在于无铁芯转子与电子换向系统的结合。其结构由以下关键部分构成: 定子组件:采用印刷电路板(PCB)或柔性电路板(FPC)作为绕组载体,通过三维绕线技术形成空心杯状绕组,彻底消除齿槽效应…...
如何修复卡在恢复模式下的 iPhone:简短指南
Apple 建议使用恢复模式作为最后的手段,以便在 iPhone 启动循环或显示 Apple 标志时恢复 iPhone。这是解决持续问题的简单方法,但您很少使用。但是,当您的 iPhone 卡住恢复模式本身时,您会怎么做?虽然 iPhone 卡在这种…...
蒋新松:中国机器人之父
名人说:路漫漫其修远兮,吾将上下而求索。—— 屈原《离骚》 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 蒋新松:中国机器人之父 一、生平简介 1. 早年经历与求学道路 蒋新松出生…...
[Windows] MousePlus 5.5.9
[Windows] MousePlus 链接:https://pan.xunlei.com/s/VOOwKJ281kDaZV5_MpP1COd_A1?pwdn69c# MousePlus是一款轻便小巧的鼠标右键增强工具,使用鼠标右键拖动即可唤醒鼠标轮盘,这个功能界面和quicker的轮盘软件界面一样,操作逻辑…...
BT131-ASEMI无人机专用功率器件BT131
编辑:ll BT131-ASEMI无人机专用功率器件BT131 型号:BT131 品牌:ASEMI 封装:TO-92 批号:最新 引脚数量:3 特性:双向可控硅 工作温度:-40℃~150℃ 在智能化浪潮中,…...
ETL架构、数据建模及性能优化实践
ETL(Extract, Transform, Load)和数据建模是构建高性能数据仓库的核心环节。下面从架构设计、详细设计、数据建模方法和最佳实践等方面系统阐述如何优化性能。 一、ETL架构设计优化 1. 分层架构设计 核心分层: 数据源层:对接O…...
30分钟上架鸿蒙原生应用,即时通信IM UI组件库全面适配HarmonyOS 原
自去年 10 月 8 日鸿蒙5开启公测以来,鸿蒙操作系统不断迭代,生态趋向稳健。当前,支持HarmonyOS操作系统的设备数量已超过 10 亿,上架HarmonyOS 5 应用市场的鸿蒙原生应用和元服务已超过2万个。这无疑为广大开发者提供了丰富的应用…...
【虚幻5蓝图Editor Utility Widget:创建高效模型材质自动匹配和资产管理工具,从3DMax到Unreal和Unity引擎_系列第二篇】
虚幻5蓝图Editor Utility Widget 一、基础框架搭建背景:1. 创建Editor Utility Widget2.根控件选择窗口3.界面功能定位与阶段4.查看继承树5.目标效果 二、模块化设计流程1.材质替换核心流程:2.完整代码如下 三、可视化界面UI布局1. 添加标题栏2. 构建滚动…...
机器学习第三篇 模型评估(交叉验证)
Sklearn:可以做数据预处理、分类、回归、聚类,不能做神经网络。原始的工具包文档:scikit-learn: machine learning in Python — scikit-learn 1.6.1 documentation数据集:使用的是MNIST手写数字识别技术,大小为70000,数据类型为7…...
php数据库连接
前言 最近在学习php,刚好学习到了php连接数据库记录一下 总结 //1、与mysql建立连接$conn mysql_connect("127.0.0.1","root","root");//设置编码mysql_set_charset(utf8);//2、选择要操作的数据库mysql_select_db("xuesheng…...
Android Studio学习记录1
Android Studio打包APK 本文为个人学习记录,仅供参考,如有错误请指出。本文主要记录在Android Studio中开发时遇到的问题和回答。 随着学习的深入,项目完成并通过测试之后免不了需要进入打包环节。这篇文章主要记录一下尝试打包APK的过程。我…...
【JAVA ee初阶】多线程(3)
一、出现线程安全的原因 1.【根本原因】线程的调度执行时随机的(抢占式执行)->罪魁祸首 2.多个线程同时修改同一个变量 如果是一个线程修改一个变量 或者 多个线程读取同一个变量 或者 多个线程修改不同变量 这些都没事。 3.修改操作不是原子的&a…...
【Java ee初阶】多线程(4)
一、java是怎么做到可重入的 java中,通过synchronized进行加锁,指定一个()包含了一个锁对象。(锁对象本身是一个啥样的对象,这并不重要,重点关注锁对象是不是同一个对象) 后面搭配…...
Day15(贪心算法)——LeetCode121.买卖股票的最佳时机55.跳跃游戏
1 LeetCode121.买卖股票的最佳时机(LeetCode121) 1.1 题目描述 题目描述如下: 示例如下: 1.2 问题分析及解决 要求最大利润,即当天与之前天的价格之差最大值。因此我们可以遍历数组,记录下当前遇到的最小值,然后用当天的价…...
2025汽车制造企业数字化转型路径参考
以应用场景作为切入点,引导相关企业推进数字化深度转型和规模化改造,是目前实践探索出来的一条可行路径。 汽车制造行业是相对集聚的制造业领域,通过搭建“转型场景图谱——转型通用工具——转型路径指引”分析框架,聚焦需求侧共…...
雷池WAF的身份认证 - GitHub
雷池支持通过 GitHub 认证的方式,让用户使用 GitHub 身份安全登录应用或网站。使用此功能需要 GitHub 账号 。 第一步:在 GitHub 创建一个 OAuth 应用 可参阅 GitHub 官方文档,创建一个 GitHub OAuth 应用,并获取应用的 ClientI…...
【Linux】第十二章 安装和更新软件包
目录 1. 什么是RPM? 2. dnf是什么,它和rpm有什么联系和区别? 3. RHEL 中如何做才能启用对第三方存储库的支持? 4. 怎么理解RHEL9中的应用流(Application Streams)和模块(Modules)? 5. RHEL9 有两个必要的软件存储…...