Java垃圾回收机制详解:从原理到实践

news2025/6/7 9:44:13

Java垃圾回收机制详解:从原理到实践

前言

垃圾回收(Garbage Collection,简称GC)是Java虚拟机自动管理内存的核心机制之一。它负责自动识别和回收不再被程序使用的内存空间,从而避免内存泄漏和溢出问题。深入理解垃圾回收机制对于Java开发者来说至关重要,它不仅能帮助我们写出更高效的代码,还能在遇到性能问题时进行有效的调优。

1. 垃圾回收基础概念

1.1 什么是垃圾

在Java中,"垃圾"指的是不再被任何对象引用的内存空间。当一个对象失去所有引用时,它就成为了垃圾,等待被垃圾回收器回收。

public class GCDemo {
    public static void main(String[] args) {
        // 创建对象
        String str = new String("Hello World");
        
        // 对象失去引用,成为垃圾
        str = null;
        
        // 此时原来的"Hello World"字符串对象成为垃圾
        System.gc(); // 建议进行垃圾回收(仅是建议)
    }
}

1.2 引用类型

Java中有四种引用类型,它们对垃圾回收的影响各不相同:

强引用(Strong Reference)
  • 默认的引用类型
  • 只要强引用存在,垃圾回收器永远不会回收被引用的对象
Object obj = new Object(); // 强引用
软引用(Soft Reference)
  • 内存空间足够时不会被回收
  • 内存空间不足时会被回收
SoftReference<Object> softRef = new SoftReference<>(new Object());
弱引用(Weak Reference)
  • 只要垃圾回收器运行,就会被回收
WeakReference<Object> weakRef = new WeakReference<>(new Object());
虚引用(Phantom Reference)
  • 无法通过虚引用获得对象实例
  • 主要用于跟踪对象被垃圾回收的状态
PhantomReference<Object> phantomRef = new PhantomReference<>(new Object(), new ReferenceQueue<>());

2. 内存区域与对象分配

2.1 堆内存结构

Java堆内存采用分代收集策略,主要分为以下区域:

堆内存
├── 年轻代(Young Generation)
│   ├── Eden区
│   ├── Survivor 0区(S0)
│   └── Survivor 1区(S1)
└── 老年代(Old Generation)

2.2 对象分配流程

public class ObjectAllocationDemo {
    public static void main(String[] args) {
        // 1. 新创建的对象首先分配到Eden区
        List<String> list = new ArrayList<>();
        
        // 2. 不断添加对象
        for (int i = 0; i < 1000000; i++) {
            list.add("Object" + i);
            
            // 当Eden区满时,触发Minor GC
            // 存活对象移到Survivor区
            // 经过多次GC后,长期存活的对象进入老年代
        }
    }
}

3. 垃圾回收算法

3.1 标记-清除算法(Mark-Sweep)

原理:

  1. 标记阶段:遍历所有可达对象,进行标记
  2. 清除阶段:回收未被标记的对象

优缺点:

  • 优点:实现简单
  • 缺点:产生内存碎片,效率不高
// 伪代码示例
public class MarkSweepGC {
    public void markSweep() {
        // 标记阶段
        markReachableObjects();
        
        // 清除阶段
        sweepUnmarkedObjects();
    }
    
    private void markReachableObjects() {
        // 从GC Roots开始,标记所有可达对象
    }
    
    private void sweepUnmarkedObjects() {
        // 回收所有未标记的对象
    }
}

3.2 复制算法(Copying)

原理:
将内存分为两个相等的区域,每次只使用其中一个。垃圾回收时,将存活对象复制到另一个区域。

适用场景:

  • 年轻代垃圾回收
  • 存活对象较少的场景
public class CopyingGCDemo {
    private Object[] fromSpace;
    private Object[] toSpace;
    private int fromPointer = 0;
    private int toPointer = 0;
    
    public void copyingGC() {
        // 将存活对象从fromSpace复制到toSpace
        copyLiveObjects();
        
        // 交换空间
        swapSpaces();
        
        // 清空原fromSpace
        clearFromSpace();
    }
}

3.3 标记-整理算法(Mark-Compact)

原理:

  1. 标记阶段:标记存活对象
  2. 整理阶段:将存活对象向内存一端移动

优缺点:

  • 优点:没有内存碎片
  • 缺点:整理过程需要移动对象,效率较低
public class MarkCompactGC {
    public void markCompact() {
        // 标记存活对象
        markLiveObjects();
        
        // 整理内存,消除碎片
        compactMemory();
    }
}

3.4 分代收集算法

核心思想:

  • 年轻代:使用复制算法
  • 老年代:使用标记-清除或标记-整理算法
public class GenerationalGCDemo {
    public void youngGenerationGC() {
        // Eden区 + Survivor区 -> Survivor区
        copyFromEdenAndSurvivorToSurvivor();
        
        // 年龄增长,达到阈值进入老年代
        promoteToOldGeneration();
    }
    
    public void oldGenerationGC() {
        // 使用标记-整理算法
        markCompactOldGeneration();
    }
}

4. 垃圾收集器详解

4.1 Serial收集器

特点:

  • 单线程收集器
  • 收集时暂停所有工作线程(Stop The World)
  • 适用于客户端模式

启用参数:

-XX:+UseSerialGC

4.2 ParNew收集器

特点:

  • Serial收集器的多线程版本
  • 年轻代并行收集器
  • 与CMS收集器配合使用

启用参数:

-XX:+UseParNewGC

4.3 Parallel Scavenge收集器

特点:

  • 关注吞吐量
  • 支持自适应调节策略
  • 年轻代并行收集器

启用参数:

-XX:+UseParallelGC
-XX:MaxGCPauseMillis=200  # 最大停顿时间
-XX:GCTimeRatio=99        # 吞吐量大小

4.4 CMS收集器(Concurrent Mark Sweep)

特点:

  • 并发收集器
  • 低停顿时间
  • 老年代收集器

收集过程:

  1. 初始标记(STW)
  2. 并发标记
  3. 重新标记(STW)
  4. 并发清除

启用参数:

-XX:+UseConcMarkSweepGC
-XX:CMSInitiatingOccupancyFraction=70  # 触发CMS收集的堆使用率

示例配置:

// JVM启动参数示例
// -Xms2g -Xmx2g -XX:+UseConcMarkSweepGC 
// -XX:+UseParNewGC -XX:CMSInitiatingOccupancyFraction=70

4.5 G1收集器(Garbage First)

特点:

  • 面向服务端应用
  • 低延迟
  • 可预测的停顿时间

内存布局:

G1堆内存布局
├── Region 1 (Eden)
├── Region 2 (Survivor)
├── Region 3 (Old)
├── Region 4 (Humongous) # 大对象区域
└── ...

启用参数:

-XX:+UseG1GC
-XX:MaxGCPauseMillis=200     # 期望的最大停顿时间
-XX:G1HeapRegionSize=16m     # Region大小

G1收集过程示例:

public class G1GCDemo {
    public static void main(String[] args) {
        // 配置G1参数
        // -XX:+UseG1GC -XX:MaxGCPauseMillis=100
        
        List<byte[]> list = new ArrayList<>();
        
        // 模拟内存分配
        for (int i = 0; i < 1000; i++) {
            // 分配不同大小的对象
            byte[] array = new byte[1024 * 1024]; // 1MB
            list.add(array);
            
            if (i % 100 == 0) {
                System.out.println("已分配 " + (i + 1) + " 个1MB对象");
            }
        }
    }
}

4.6 ZGC和Shenandoah收集器

ZGC特点:

  • 超低延迟收集器
  • 停顿时间不超过10ms
  • 支持TB级别堆内存

启用参数:

-XX:+UnlockExperimentalVMOptions -XX:+UseZGC

5. GC调优实践

5.1 GC监控和分析

常用工具:

  1. jstat - 监控GC统计信息
  2. jmap - 生成堆转储
  3. jvisualvm - 可视化监控工具
  4. GCViewer - GC日志分析工具

监控脚本示例:

#!/bin/bash
# GC监控脚本

# 获取Java进程PID
PID=$(jps | grep "YourApp" | awk '{print $1}')

# 监控GC情况
echo "=== GC监控开始 ==="
jstat -gc $PID 5s

5.2 GC日志配置

JDK 8及以前版本:

-XX:+PrintGC
-XX:+PrintGCDetails
-XX:+PrintGCTimeStamps
-XX:+PrintGCApplicationStoppedTime
-Xloggc:gc.log

JDK 9及以后版本:

-Xlog:gc:gc.log:time,level,tags

5.3 调优策略

内存分配调优
public class MemoryTuningDemo {
    public static void main(String[] args) {
        // 预分配集合容量,减少扩容带来的GC压力
        List<String> list = new ArrayList<>(10000);
        
        // 使用对象池技术,减少对象创建
        ObjectPool<StringBuilder> pool = new ObjectPool<StringBuilder>() {
            @Override
            protected StringBuilder create() {
                return new StringBuilder();
            }
            
            @Override
            protected void reset(StringBuilder obj) {
                obj.setLength(0);
            }
        };
        
        StringBuilder sb = pool.acquire();
        try {
            sb.append("Hello World");
            // 使用StringBuilder
        } finally {
            pool.release(sb);
        }
    }
}

// 简单的对象池实现
abstract class ObjectPool<T> {
    private final Queue<T> pool = new ConcurrentLinkedQueue<>();
    
    public T acquire() {
        T object = pool.poll();
        return object != null ? object : create();
    }
    
    public void release(T object) {
        reset(object);
        pool.offer(object);
    }
    
    protected abstract T create();
    protected abstract void reset(T object);
}
参数调优示例
# 生产环境G1调优参数示例
java -Xms4g -Xmx4g \
     -XX:+UseG1GC \
     -XX:MaxGCPauseMillis=100 \
     -XX:G1HeapRegionSize=16m \
     -XX:G1NewSizePercent=30 \
     -XX:G1MaxNewSizePercent=40 \
     -XX:G1MixedGCCountTarget=8 \
     -XX:InitiatingHeapOccupancyPercent=45 \
     -XX:+G1PrintRegionRememberedSetInfo \
     -Xlog:gc:gc.log:time,level,tags \
     YourApplication

5.4 常见问题与解决方案

问题1:Full GC频繁

可能原因:

  • 老年代空间不足
  • 元数据区空间不足
  • 内存泄漏

解决方案:

// 1. 增加堆内存
-Xms8g -Xmx8g

// 2. 调整年轻代比例
-XX:NewRatio=2  // 老年代:年轻代 = 2:1

// 3. 增加元数据区大小
-XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=512m
问题2:GC停顿时间过长

解决方案:

// 使用G1收集器,设置期望停顿时间
-XX:+UseG1GC -XX:MaxGCPauseMillis=100

// 或者使用ZGC(JDK 11+)
-XX:+UnlockExperimentalVMOptions -XX:+UseZGC
问题3:内存泄漏检测
public class MemoryLeakDemo {
    private static final Map<String, Object> cache = new HashMap<>();
    
    public static void main(String[] args) {
        // 模拟内存泄漏 - 对象不断添加到静态集合中
        Timer timer = new Timer();
        timer.scheduleAtFixedRate(new TimerTask() {
            private int counter = 0;
            
            @Override
            public void run() {
                // 不断添加对象,但从不清理
                cache.put("key" + counter++, new byte[1024 * 1024]);
                
                if (counter % 100 == 0) {
                    System.out.println("Cache size: " + cache.size());
                    System.out.println("Free memory: " + 
                        Runtime.getRuntime().freeMemory() / 1024 / 1024 + " MB");
                }
            }
        }, 0, 100);
    }
}

检测方法:

# 生成堆转储
jmap -dump:format=b,file=heap.hprof <pid>

# 使用MAT或jvisualvm分析堆转储文件

6. 实际应用案例

6.1 高并发Web应用调优

场景:

  • 日PV 1000万+
  • 并发用户数10000+
  • 99%请求响应时间 < 100ms

调优方案:

# JVM参数配置
-Xms8g -Xmx8g
-XX:+UseG1GC
-XX:MaxGCPauseMillis=50
-XX:G1HeapRegionSize=16m
-XX:G1NewSizePercent=40
-XX:G1MaxNewSizePercent=50
-XX:InitiatingHeapOccupancyPercent=35
-XX:+UnlockExperimentalVMOptions
-XX:G1MixedGCLiveThresholdPercent=85

应用代码优化:

@Component
public class CacheOptimizedService {
    
    // 使用Caffeine本地缓存,减少GC压力
    private final Cache<String, Object> localCache = Caffeine.newBuilder()
            .maximumSize(10000)
            .expireAfterWrite(Duration.ofMinutes(10))
            .build();
    
    // 对象池化,减少频繁创建销毁
    private final ObjectPool<StringBuilder> stringBuilderPool = 
        new GenericObjectPool<>(new StringBuilderFactory());
    
    public String processData(String input) {
        // 先从缓存获取
        Object cached = localCache.getIfPresent(input);
        if (cached != null) {
            return (String) cached;
        }
        
        // 使用对象池
        StringBuilder sb = null;
        try {
            sb = stringBuilderPool.borrowObject();
            sb.append("Processed: ").append(input);
            String result = sb.toString();
            
            localCache.put(input, result);
            return result;
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            if (sb != null) {
                try {
                    stringBuilderPool.returnObject(sb);
                } catch (Exception e) {
                    // 忽略归还异常
                }
            }
        }
    }
}

6.2 大数据处理应用调优

场景:

  • 单次处理数据量:1TB+
  • 内存使用:32GB+
  • 要求:低延迟,高吞吐

调优方案:

# 大堆内存配置
-Xms32g -Xmx32g
-XX:+UseG1GC
-XX:MaxGCPauseMillis=200
-XX:G1HeapRegionSize=32m
-XX:ParallelGCThreads=16
-XX:ConcGCThreads=8
-XX:+UnlockExperimentalVMOptions
-XX:+UseTransparentHugePages

数据处理优化:

public class BigDataProcessor {
    
    // 使用NIO和内存映射文件,减少GC压力
    public void processLargeFile(String filePath) throws IOException {
        try (RandomAccessFile file = new RandomAccessFile(filePath, "r");
             FileChannel channel = file.getChannel()) {
            
            long fileSize = channel.size();
            long chunkSize = 1024 * 1024 * 1024; // 1GB chunks
            
            for (long position = 0; position < fileSize; position += chunkSize) {
                long size = Math.min(chunkSize, fileSize - position);
                
                // 使用内存映射,减少对象创建
                MappedByteBuffer buffer = channel.map(
                    FileChannel.MapMode.READ_ONLY, position, size);
                
                processChunk(buffer);
                
                // 强制释放映射
                unmapBuffer(buffer);
            }
        }
    }
    
    private void processChunk(ByteBuffer buffer) {
        // 流式处理,避免一次性加载大量对象到内存
        while (buffer.hasRemaining()) {
            // 处理数据...
        }
    }
    
    private void unmapBuffer(MappedByteBuffer buffer) {
        try {
            Method cleanerMethod = buffer.getClass().getMethod("cleaner");
            cleanerMethod.setAccessible(true);
            Object cleaner = cleanerMethod.invoke(buffer);
            if (cleaner != null) {
                Method cleanMethod = cleaner.getClass().getMethod("clean");
                cleanMethod.invoke(cleaner);
            }
        } catch (Exception e) {
            // JDK版本兼容性处理
        }
    }
}

7. 最佳实践总结

7.1 开发阶段

  1. 对象生命周期管理

    • 及时释放不需要的引用
    • 使用局部变量替代成员变量
    • 避免在循环中创建大量临时对象
  2. 集合使用优化

    • 预估集合大小,避免频繁扩容
    • 选择合适的集合类型
    • 及时清理不使用的集合元素
  3. 字符串处理优化

    • 大量字符串拼接使用StringBuilder
    • 避免不必要的字符串创建
    • 合理使用字符串常量池

7.2 生产环境

  1. 监控体系建设

    • 配置GC日志
    • 设置GC监控告警
    • 定期分析GC报告
  2. 参数调优

    • 根据应用特点选择合适的收集器
    • 合理设置堆内存大小
    • 调整GC触发条件
  3. 性能测试

    • 压力测试验证GC性能
    • 长时间运行测试检查内存泄漏
    • 不同负载下的GC表现分析

结语

Java垃圾回收机制是一个复杂而精巧的系统,它在很大程度上简化了Java开发者的内存管理工作。但是,要想写出高性能的Java应用,深入理解GC原理和掌握调优技巧仍然是必不可少的。

随着Java版本的不断更新,垃圾回收技术也在持续进化。从传统的串行收集器到现代的ZGC和Shenandoah,Java的GC性能得到了显著提升。作为开发者,我们需要保持学习,跟上技术发展的步伐,在实际项目中灵活运用这些知识,为用户提供更好的体验。

记住,GC调优不是一蹴而就的过程,需要结合具体的应用场景、业务特点和性能要求进行综合考虑。只有在充分理解原理的基础上,才能做出正确的调优决策。


本文涵盖了Java垃圾回收的核心概念、算法原理、收集器对比和实践调优等内容。如果您在实际应用中遇到GC相关问题,建议结合具体场景进行分析,必要时可以寻求专业的性能调优服务支持。

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

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

相关文章

微服务架构下的服务注册与发现:Eureka 深度解析

&#x1f4e6; 一、引言 &#x1f310; 微服务架构中服务注册与发现的核心价值 在微服务架构中&#xff0c;服务注册与发现是支撑系统可扩展性、高可用性和动态管理的关键基础。 ✅ 核心价值解析 动态扩展与弹性伸缩 服务实例可随时上线/下线&#xff0c;无需手动更新配置&am…

Qt/C++学习系列之QButtonGroup的简单使用

Qt/C学习系列之QButtonGroup的简单使用 前言QButtonGroup刨析源码 具体使用界面设计具体函数使用初始化信号与槽函数&#xff08;两种方式&#xff09; 总结 前言 在练手项目中&#xff0c;使用了QButtonGroup。项目需求有互斥的要求&#xff0c;在使用QRadioButton的基础上&a…

CETOL 6σ v12.1 三维公差分析软件现已可供下载

一、新版本发布 德克萨斯州麦金尼 — 2025年6月5日 —Sigmetrix 宣布其最新版本的 CETOL 6σ 公差分析软件&#xff08;v12.1&#xff09;现已可供立即下载。公差分析在诸多方面为企业发展带来益处。它通过平衡质量与制造成本&#xff0c;助力企业提升盈利能力。企业还可借此缩…

【JavaEE】Spring Boot项目创建

Spring Boot介绍 在学习Spring Boot之前&#xff0c;我们先来认识一下Spring Spring官方是这样介绍的&#xff1a; 可以看到&#xff0c;Spring让Java程序更加快速&#xff0c;简单和安全。Spring对于速度&#xff0c;简单性和生产力的关注使其成为世界上最流行的Java框架 Sp…

KAG与RAG在医疗人工智能系统中的多维对比分析

1、引言 随着人工智能技术的迅猛发展,大型语言模型(LLM)凭借其卓越的生成能力在医疗健康领域展现出巨大潜力。然而,这些模型在面对专业性、时效性和准确性要求极高的医疗场景时,往往面临知识更新受限、事实准确性不足以及幻觉问题等挑战。为解决这些问题,检索增强生成(…

从零到一:Maven 快速入门教程

目录 Maven 简介Maven 是什么为什么使用 Maven&#xff1f; 安装 Maven下载 Maven 配置 Maven解压文件配置本地仓库保存路径配置国内仓库地址 Maven 的核心概念了解 pom.xml 文件坐标依赖范围生命周期compileprovidedruntimetestsystemimport 依赖传递依赖排除依赖循环 继承1. …

postman基础

前言 本次 Chat 将结合业界广为推崇和使用的 RestAPI 设计典范 Github API&#xff0c;详细介绍 Postman 接口测试工具的使用方法和实战技巧。 在开始这个教程之前&#xff0c;先聊一下为什么接口测试在现软件行业如此重要&#xff1f; 为什么我们要学习 Postman&#xff1f;…

python训练营day45

知识点回顾&#xff1a; tensorboard的发展历史和原理tensorboard的常见操作tensorboard在cifar上的实战&#xff1a;MLP和CNN模型 效果展示如下&#xff0c;很适合拿去组会汇报撑页数&#xff1a; 作业&#xff1a;对resnet18在cifar10上采用微调策略下&#xff0c;用tensorbo…

Halcon透视矩阵

在 Halcon中&#xff0c;透视变换矩阵用于将图像从一个视角转换到另一个视角&#xff0c;常用于图像校正和几何变换。以下是计算透视变换矩阵的步骤及代码示例。 透视形变图像校正的步骤 对图像左简单的处理&#xff0c;分割要校正的区域&#xff1b;提取区域的顶点坐标信息&…

007-nlohmann/json 项目应用-C++开源库108杰

本课为 fswatch&#xff08;第一“杰”&#xff09;的示例项目加上对配置文件读取的支持&#xff0c;同时借助 第三“杰” CLI11 的支持&#xff0c;完美实现命令行参数与配置文件的逻辑统一。 012-nlohmann/json-4-项目应用 项目基于原有的 CMake 项目 HelloFSWatch 修改。 C…

移动端测试岗位高频面试题及解析

文章目录 一、基础概念二、自动化测试三、性能测试四、专项测试五、安全与稳定性六、高级场景七、实战难题八、其他面题 一、基础概念 移动端测试与Web测试的核心区别&#xff1f; 解析&#xff1a;网络波动&#xff08;弱网测试&#xff09;、设备碎片化&#xff08;机型适配&…

Git GitHub Gitee

一、Git 是一个免费、开源的分布式版本控制系统。 版本控制&#xff1a;一种记录文件内容变化&#xff0c;以便将来查阅特定版本修订情况的系统。它最重要的就是可以记录文件修改历史记录&#xff0c;从而让用户可以看历史版本&#xff0c;方便版本切换。 1.和集中式版本控制…

PLSQLDeveloper配置OracleInstantClient连接Oracle数据库

PL/SQLDeveloper配置Oracle Instant Client连接Oracle数据库 文章目录 PL/SQLDeveloper配置Oracle Instant Client连接Oracle数据库 1. Oracle Instant Client下载与配置1. Oracle Instant Client下载2. Oracle Instant Client解压配置1. 解压2. 配置 2. PL/SQL Developer下载、…

【Oracle】触发器

个人主页&#xff1a;Guiat 归属专栏&#xff1a;Oracle 文章目录 1. 触发器基础概述1.1 触发器的概念与特点1.2 触发器的分类1.3 触发器的执行顺序 2. DML触发器2.1 基础DML触发器2.1.1 INSERT触发器2.1.2 UPDATE触发器2.1.3 DELETE触发器 2.2 高级DML触发器2.2.1 复合触发器2…

基于深度学习的无人机轨迹预测

完整代码见文末 随着无人机技术的不断发展&#xff0c;无人机在农业、物流、监控等领域的应用日益广泛。精准的轨迹预测不仅能够提高无人机飞行的效率和安全性&#xff0c;还能在应对复杂环境下的突发状况时做出迅速反应。因此&#xff0c;基于深度学习的无人机轨迹预测已成为…

git连接本地仓库以及gitee

参考:gitee创建新仓库并上传代码_gitee新建仓库导入代码-CSDN博客 git初始化以及添加git分支 在idea查看master主分支 报错 原因gitee推送更新失败问题记录&#xff1a;remote: error: hook declined to update refs/heads/master-CSDN博客 取消邮箱暴露

麒麟v10系统的docker重大问题解决-不支持容器名称解析

今天给客户在麒麟v10Kylin-Server-V10-SP1下安装nextcloudonlyoffice的时候出现无法连接onlyoffice的问题,经过分析找到了是docker版本过低的原因,现在把解决思路和步骤分享给大家。 一、问题 用一键安装工具,给客户装好了系统,Nextcloud可以正常访问 但是访问nextcloud中的o…

基于5G下行信号的模糊函数分析matlab仿真,对比速度模糊函数和距离模糊函数

目录 1.引言 2.算法仿真效果演示 3.数据集格式或算法参数简介 4.MATLAB部分程序 5.算法涉及理论知识概要 6.参考文献 7.完整算法代码文件获得 1.引言 模糊函数&#xff08;Ambiguity Function, AF&#xff09;是信号处理领域用于分析信号时频分辨能力的核心工具&#xf…

Redis 过期了解

Redis 版本&#xff1a;5.0 &#xff1a; 一&#xff1a;过期监听&#xff1a; Spring Data Redis 封装了 Redis 的 Pub/Sub 功能&#xff0c;提供了对 key 过期事件的监听支持。 1. 核心类&#xff1a;KeyExpirationEventMessageListener 这个抽象类是 Spring 提供的&#x…

JAVA理论-JAVA基础知识

1.Java 基础 知识 1.1 面向对象的特征&#xff08;了解&#xff09; 面向对象的特征&#xff1a;封装、继承、多态、抽象 封装&#xff1a;就是把对象的属性和行为&#xff08;数据&#xff09;结合为一个独立的整体&#xff0c;并尽量隐藏对象的内部细节&#xff0c;公开我希…