JVM基础1:内存区域、GC垃圾回收算法

JVM 运行时五大内存分区分类、存储内容与对应异常

内存分区两大分类标准(线程私有 / 线程共享)

JVM 运行时数据区分为两类,核心区别:是否每个线程独立拥有内存、是否容易产生 OOM

  • 线程私有(单线程独占,线程销毁内存直接释放,OOM 概率低)
    • 程序计数器 PC Register
    • 虚拟机栈 JVM Stack
    • 本地方法栈 Native Method Stack
  • 线程共享(整个进程共用,进程关闭才释放内存,高频出现 OOM)
    • 堆 Heap(GC 主要回收区域)
    • 方法区 Method Area(JDK8 后为元空间 Metaspace)

OutOfMemoryError内存溢出

JVM 运行程序时,需要分配一块内存存放对象、类、缓冲区等,但没有足够空闲内存满足本次分配需求,虚拟机直接抛出 OOM 异常,严重时服务进程崩溃。

和 StackOverflowError 区分
  • StackOverflowError:栈深度超限,递归死循环、方法嵌套太多;栈空间本身是够的,只是层数放不下。
  • OOM:整块内存容量耗尽,分配新内存失败。
五种常见 OOM 类型
  1. Java heap space 堆内存溢出。new 的对象、数组太多,GC 回收后依然没有空闲空间。 场景:内存泄漏、无限创建对象、超大集合缓存数据。

  2. Metaspace 元空间溢出。大量动态生成类:CGLIB 代理、频繁反射、热加载、动态脚本。

  3. Direct buffer memory 堆外直接内存溢出。NIO 读写文件 / 网络,DirectByteBuffer 堆外内存没手动释放。

  4. 虚拟机栈 OOM 栈支持动态扩容,操作系统无剩余内存分配新栈帧,极少出现。

  5. 本地方法栈 OOM native 方法申请本地内存耗尽,线上几乎遇不到。

OOM 根本两大诱因
  1. 内存参数设置过小:-Xmx 堆最大值、元空间上限配置太低;
  2. 代码内存泄漏:无用对象被强引用持续持有,GC 永远无法回收,内存慢慢占满。

私有三区:计数器、虚拟机栈、本地方法栈,随线程销毁;

共享两区:堆、元空间,全局共用易 OOM;

堆存对象、元空间存类信息,栈只存引用不存实体对象。

五大内存区域逐点详解

内存区域 线程归属 存储内容 内存回收方式 对应异常 调优参数
程序计数器 线程私有 当前线程执行的字节码指令地址 线程销毁自动释放 无 OOM(唯一不会溢出)
虚拟机栈 线程私有 栈帧:局部变量表、操作数栈、动态链接、方法出口;存放基本类型、对象引用地址 方法执行完栈帧自动出栈,无 GC 参与 StackOverflowError(栈深度超限)/ 栈 OOM(扩容失败) -Xss(单个栈大小)
本地方法栈 线程私有 native 底层 C/C++ 方法栈帧 方法执行完自动释放 StackOverflowError / 栈 OOM -Xss
堆 Heap 线程共享 所有 new 创建的对象实例、数组实体;细分为新生代(Eden、S0、S1)、老年代 GC 垃圾回收自动清理无用对象 java.lang.OutOfMemoryError: Java heap space -Xms(初始堆)/-Xmx(最大堆)
方法区(元空间) 线程共享 类字节码、静态变量、运行时常量池、类 / 方法 / 字段描述信息 Full GC 时回收废弃类、常量 java.lang.OutOfMemoryError: Metaspace -XX:MaxMetaspaceSize

程序计数器(PC 寄存器)

  1. 归属:线程私有
  2. 核心作用:记录当前线程执行到的字节码行号;多线程切换时,依靠该记录恢复执行位置
  3. 存储内容:字节码指令地址
  4. 异常特性:JVM 规范唯一不会发生 OOM 的内存区域

虚拟机栈(Java 栈)

  1. 归属:线程私有
  2. 存储载体:栈帧,每调用一个方法就创建一个栈帧,方法执行完毕栈帧出栈销毁
  3. 栈帧内部组成:局部变量表、操作数栈、动态链接、方法出口
  4. 存储数据:方法内局部基本数据类型、对象引用地址
  5. 抛出两类异常:
    • StackOverflowError:递归死循环、多层方法嵌套,栈深度超出最大限制
    • OutOfMemoryError:虚拟机栈支持动态扩容,系统剩余内存不足无法分配新栈帧

本地方法栈

  1. 归属:线程私有
  2. 作用:专门执行 native 本地方法(底层 C/C++ 系统调用、IO 操作等)
  3. 结构、异常类型和虚拟机栈完全一致,同样会栈溢出、内存溢出

堆 Heap(重点)

  1. 归属:线程共享,整个 JVM 最大内存区域,GC 核心回收区
  2. 存储内容:所有 new 关键字创建的对象实例、数组实体
  3. 堆内存细分:新生代(Eden 区、Survivor0、Survivor1)、老年代 Old 区
  4. 溢出异常:java.lang.OutOfMemoryError: Java heap space 触发场景:对象过多、大对象、内存泄漏,堆内存分配不足

方法区(JDK8 元空间 Metaspace)

  1. 归属:线程共享
  2. 版本变化:JDK1.7 及之前永久代 PermGen;JDK1.8 彻底移除永久代,使用堆外本地内存元空间
  3. 存储内容:类字节码文件、静态变量、运行时常量池、方法 / 字段描述、接口信息
  4. 溢出异常:java.lang.OutOfMemoryError: Metaspace 触发场景:大量动态代理 CGLIB、频繁反射、动态生成类

补充知识点:堆外直接内存 Direct Buffer(高频 OOM )

  1. 不属于五大运行时内存区,但线上极易溢出
  2. 来源:NIO 的 DirectByteBuffer,读写文件、网络 IO 使用堆外内存
  3. 限制:不受 - Xmx 堆内存参数管控
  4. 溢出异常:java.lang.OutOfMemoryError: Direct buffer memory

虚拟机栈与堆内存核心对比表

对比维度 虚拟机栈 堆内存
线程归属 线程私有 线程共享
存储数据 局部变量、基本类型、对象引用地址 new 创建的对象、数组实体
内存回收机制 方法执行完自动释放,无 GC 参与 依靠 GC 垃圾回收清理无用对象
溢出类型 StackOverflowError、栈 OOM Java heap space 堆内存溢出
内存参数控制 -Xss 控制单个栈大小 -Xms/-Xmx 控制堆初始 / 最大内存
生命周期 跟随线程,线程销毁栈直接释放 跟随进程,GC 持续回收闲置对象

判断对象存活的两种算法(引用计数、可达性分析 GC Roots)

判断算法 实现逻辑 优点 致命缺点 JVM 是否使用
引用计数 对象自带计数器,引用 ±1,0 则回收 逻辑简单,实时回收 循环引用无法回收,内存泄漏 不使用
可达性分析 GC Roots 从根对象遍历引用链,不可达为垃圾 解决循环引用,回收准确 需要扫描全堆,产生 STW 停顿 HotSpot 默认,全行业通用

引用计数算法(已淘汰,仅理论了解)

核心原理

给每一个 Java 对象单独维护一个整型引用计数器:

  1. 当有变量引用该对象,计数器 +1
  2. 引用失效(变量销毁、重新赋值),计数器 -1
  3. 计数器数值为 0,判定为垃圾对象,可被 GC 回收。

致命缺陷(无法商用)

循环引用问题 两个对象 A、B,A 内部持有 B 的引用,B 内部持有 A 的引用;外部无任何变量指向 A 和 B。 此时两者计数器都不为 0,GC 永远识别不了这是垃圾,无法回收,长期堆积造成内存泄漏、堆 OOM。

结论

HotSpot 虚拟机完全放弃该算法。

可达性分析算法(HotSpot 虚拟机默认,生产主流)

核心逻辑

定义一系列GC Roots 根对象作为起点,从根向下遍历整个引用链:

  1. 遍历过程中能够访问到的对象 = 存活对象;
  2. 从 GC Roots 出发无法遍历到达的对象 = 垃圾对象,等待 GC 回收;
  3. 完美解决循环引用的痛点。

五类标准 GC Roots

  1. 虚拟机栈中局部变量引用的对象(方法内创建的对象);
  2. 方法区中静态变量、常量引用的对象(static 全局集合、常量对象);
  3. 本地方法栈 native 方法引用的底层对象;
  4. 同步锁 synchronized 持有的 monitor 锁对象;
  5. Java 系统内置对象:主线程、类加载器、系统 Class 等。

可达性分析完整执行流程

  1. 第一步:找到全部 GC Roots 收集虚拟机栈、静态变量、native 方法、锁、系统线程等根对象。
  2. 第二步:遍历引用链 以 GC Roots 为起点顺着对象引用一路遍历,沿途接触到的全部标记存活。
  3. 第三步:区分存活 / 垃圾 能走到 = 存活;完全走不到、无任何根可达 = 垃圾对象。
  4. 第四步:回收垃圾 根据 GC 算法(复制 / 标记清除 / 标记整理)清理垃圾,释放堆内存。
  5. 核心优势:即使两个对象互相循环引用,只要 GC Roots 碰不到,照样判定垃圾回收,解决引用计数致命问题。

对象四大引用类型

  1. 强引用Object o = new Object() 只要存在强引用,GC 永远不会回收,日常代码默认使用,静态集合极易靠强引用造成内存泄漏。
  2. 软引用 SoftReference 内存充足不回收,堆空间即将溢出时才回收;适合做缓存。
  3. 弱引用 WeakReference 只要发生 GC,无论内存是否充足都会被回收;缓存、临时映射场景使用。
  4. 虚引用 PhantomReference 无法通过引用获取对象,仅用于监控对象被回收的通知,极少业务使用。
引用类型 定义说明 GC 回收时机 常见使用场景 JDK 对应类 举例说明
强引用 普通new对象赋值给变量,默认就是强引用 只要强引用存在,GC永远不会回收;即使 OOM 也不回收 日常业务代码默认使用,绝大部分对象都是强引用 无特殊类,默认即强引用 Object obj = new Object()
软引用 SoftReference 用 SoftReference 包装对象,内存充足时保留 内存充足时不回收;堆内存即将 OOM 溢出时才回收 内存敏感型缓存:图片缓存、大对象缓存 java.lang.ref.SoftReference 浏览器图片缓存,内存够就留着,不够就清掉
弱引用 WeakReference 用 WeakReference 包装对象,生命周期比软引用更短 只要发生 GC,无论内存是否充足,都会被回收 临时映射、ThreadLocal、缓存、避免内存泄漏 java.lang.ref.WeakReference ThreadLocal 的 key 就是弱引用,防止 ThreadLocal 内存泄漏
虚引用 PhantomReference 最弱的引用,完全不影响对象生命周期,无法通过引用获取对象 对象被回收时收到通知,仅用于监控对象回收 堆外内存回收跟踪、NIO DirectByteBuffer 回收监控 java.lang.ref.PhantomReference 监控堆外直接内存释放,避免 DirectBuffer 泄漏

强引用:默认就是,永不回收,OOM 也不丢; 软引用:内存不够才回收,适合做大缓存;

弱引用:遇到 GC 就回收,适合临时映射; 虚引用:拿不到对象,只用来监控回收通知。

四大基础 GC 垃圾回收算法(原理、优缺点、适用区域)

标记 - 清除算法 Mark-Sweep

执行流程

  1. 标记阶段:从 GC Roots 遍历堆,把所有存活对象打上标记;
  2. 清除阶段:扫描整个堆,直接释放所有未标记的垃圾对象内存。

优点

实现逻辑简单,不需要移动任何存活对象。

缺点

  1. 回收完成后产生大量不连续内存碎片;分配大对象时找不到连续空间,频繁触发 Full GC;
  2. 需要两次完整遍历堆内存,GC 效率偏低。

适用场景

仅老年代简易回收场景,生产环境不会单独使用。

复制算法 Copying

执行流程

将内存划分为两块同等大小区域 A、B;

  1. 平时只使用 A 区存放新对象;
  2. GC 触发时,把 A 区内所有存活对象复制到空白 B 区,保证内存连续;
  3. 复制完成后直接清空 A 区,交换 A、B 角色,下一次 GC 复用。

优点

  1. 复制后内存完全连续,无内存碎片;
  2. 分配对象速度快,仅移动指针即可分配。

缺点

  1. 永久浪费一半堆内存空间;
  2. 存活对象数量多时,复制成本极高,停顿时间变长。

适用场景

新生代(Eden+Survivor),新生代大部分对象朝生夕死,存活对象极少,复制开销很低。

标记 - 整理算法 Mark-Compact

执行流程

  1. 标记阶段:同标记清除,标记全部存活对象;
  2. 整理阶段:将所有存活对象向内存一端压缩、移动,全部紧凑排列;
  3. 边界以外整块空间全部清空,形成连续空闲内存。

优点

回收后无内存碎片,空闲内存连续,适合存放大对象。

缺点

需要大量移动存活对象,STW 停顿时间很长,性能损耗大。

适用场景

老年代(老年代存活对象多,复制算法浪费一半内存,不适合)。

分代收集算法 Generational Collection(商用主流组合算法)

核心思想

根据对象存活生命周期把堆分为新生代、老年代,不同分代匹配最优回收算法:

  1. 新生代:对象生命周期短、存活少 → 复制算法
  2. 老年代:对象长期存活、数量多 → 标记清除 / 标记整理

业务执行流程

  1. 新创建对象分配在 Eden 区;
  2. Eden 占满触发 Minor GC,存活对象复制到 Survivor;
  3. 多次 GC 仍存活的对象晋升到老年代;
  4. 老年代空间不足,触发 Full GC,使用标记整理回收。

优点

结合复制、标记整理两者优势,综合性能最优,所有商用回收器(Parallel GC、CMS、G1、ZGC)底层均基于分代收集。

缺点

需要维护两套回收逻辑,虚拟机底层实现复杂。

GC 算法 核心流程 优点 缺点 适用内存区域
标记清除 标记存活对象,直接清理垃圾 实现简单,无需移动对象 产生大量内存碎片,两次全堆遍历效率低 老年代简易场景,不单独生产使用
复制 存活对象复制到备用分区,清空原分区 无内存碎片,对象分配速度快 永久浪费 50% 内存,存活多复制开销大 新生代 Eden/Survivor
标记整理 标记存活,全部向一端压缩移动 无内存碎片,空闲空间连续 大量移动对象,STW 停顿时间长 老年代
分代收集 新生代复制、老年代标记整理组合使用 分代适配,综合性能最优 多代逻辑管理复杂 完整堆内存,线上通用标准

高并发营销场景完整 JVM 内存 & GC 串联实战流程

业务场景描述

营销大促,大量用户同时领取优惠券、下单,循环创建优惠券 DTO、订单临时对象。

对象分配与 GC 完整流程

  1. 用户并发请求,代码执行 new 创建大量临时对象,全部分配到新生代 Eden 区;
  2. Eden 区快速被占满,触发 Minor GC;
  3. 大部分一次性临时请求对象无外部引用,直接被回收;少量缓存、待支付订单存活对象,通过复制算法转移到 Survivor 区;
  4. 存活对象每经历一次 Minor GC,年龄 + 1;多次 GC 后仍存活的长期缓存对象(优惠券活动缓存、用户基础信息),达到年龄阈值晋升到老年代;
  5. 若代码存在全局静态 Map 无限存入用户数据,老年代对象持续增长;
  6. 老年代剩余空间不足以容纳新晋升对象,触发 Full GC,采用标记整理算法压缩回收无效老年代对象;
  7. 若堆内存参数配置过小,Full GC 后依然没有连续空闲内存分配对象,抛出 Java heap space OOM,服务宕机;
  8. 代码大量使用 CGLIB 动态代理、反射生成类,类字节码持续填充元空间,最终触发 Metaspace 元空间溢出 OOM。

该场景下会出现的两类线上故障

故障 1:频繁 Minor GC,接口轻微卡顿

  • 现象:接口响应变慢,无大量报错,GC 日志 Minor GC 频率极高
  • 根因:循环内不停 new 临时大对象、未复用实体 DTO,Eden 快速填满
  • 优化:对象池复用对象、缩小方法外对象生命周期、调大新生代 Xmn 参数

故障 2:频繁 Full GC,CPU 打满、大量接口超时

  • 现象:CPU 持续 100%,大量请求超时,日志频繁打印 Full GC
  • 根因:全局静态集合内存泄漏、大对象直接进入老年代、堆内存配置不足
  • 应急方案:导出 dump 文件,MAT 工具分析内存占用;临时调大 - Xmx 堆内存;业务低峰期修复内存泄漏代码

短期临时对象 → 新生代 + Minor GC(复制算法)

长期缓存静态对象 → 老年代 + Full GC(标记整理)

动态生成代理类 / 反射 → 元空间溢出 OOM

线上 JVM 内存 / GC 故障分级、现象、应急处理方案

一级故障:频繁 Minor GC,接口轻微卡顿

现象

  1. GC 日志短时间大量打印 Minor GC;
  2. 接口响应延迟小幅上涨,无大批量超时、无服务宕机;
  3. CPU 轻度升高,未打满。

根因

  1. 循环逻辑中持续 new 临时对象、DTO 未复用;
  2. 新生代 Eden 内存分配过小;
  3. 单次请求创建大量短生命周期大对象。

应急处理

  1. 临时调大新生代参数 -Xmn,扩大 Eden 容量;
  2. 临时限流降低并发请求量。

长期优化

  1. 抽取通用 DTO,复用对象减少 new 次数;
  2. 局部方法内创建临时对象,避免提升生命周期;
  3. 拆分超大集合、分批处理数据。

二级故障:频繁 Full GC,CPU 打满,大量接口超时

现象

  1. 日志持续输出 Full GC;
  2. CPU 占用长期接近 100%;
  3. 前端大批量请求超时,服务吞吐量暴跌。

根因

  1. 静态 Map/List 无限存放数据,内存泄漏;
  2. 超大对象直接分配到老年代;
  3. 堆内存 -Xmx 设置过小;
  4. 老年代无连续内存存放晋升对象。

应急处理

  1. 立即开启 dump 快照,使用 MAT 工具分析内存占用;
  2. 临时调高 -Xmx 堆最大内存缓解压力;
  3. 临时下线高耗内存活动接口。

长期优化

  1. 清理全局静态集合,采用软 / 弱引用做业务缓存;
  2. 限制单次查询返回数据量,拆分大对象;
  3. 调整对象晋升年龄阈值,优化分代内存比例。

三级故障:StackOverflowError 栈溢出,服务崩溃

现象

控制台抛出 StackOverflowError,进程直接重启崩溃。

根因

  1. 递归逻辑无终止条件,无限递归;
  2. 多层方法循环嵌套过深;
  3. 单线程栈内存 -Xss 配置偏小。

应急处理

  1. 紧急修复递归代码,增加递归深度判断终止条件;
  2. 临时调大 -Xss 单栈内存大小。

长期优化

  1. 递归改循环实现业务;
  2. 递归业务增加最大深度拦截校验。

四级故障:Metaspace 元空间 OOM

现象

报错 java.lang.OutOfMemoryError: Metaspace,服务宕机。

根因

  1. CGLIB、动态代理、反射频繁生成新类;
  2. 热加载框架重复加载类,废弃类无法卸载;
  3. 元空间上限参数过小。

应急处理

  1. 临时调大 -XX:MaxMetaspaceSize
  2. 临时关闭非必要动态代理、热更新功能。

长期优化

  1. 缓存代理类,避免循环生成 Class;
  2. 定期清理无用动态类,配置类卸载参数。

五级故障:堆外直接内存 Direct Buffer OOM

现象

报错 Direct buffer memory,IO、文件上传接口异常。

根因

  1. NIO 使用 DirectByteBuffer 未手动释放堆外内存;
  2. 大文件一次性读取,缓冲区无限制;
  3. 堆外内存上限参数过小。

应急处理

  1. 限制单次上传 / 读取文件大小;
  2. 调高 -XX:MaxDirectMemorySize

长期优化

  1. 使用 try-finally 主动释放堆外缓冲区;
  2. 文件流分段读写,不一次性加载全部文件。
故障等级 故障类型 核心现象 快速应急手段
一级 频繁 Minor GC 接口轻微卡顿、GC 日志 Minor GC 多 调大 - Xmn、临时限流
二级 频繁 Full GC CPU100%、大量请求超时 导出 dump、调高 - Xmx、下线高耗内存接口
三级 栈溢出 StackOverflowError 程序直接崩溃重启 修复递归逻辑、增大 - Xss
四级 元空间 OOM Metaspace 溢出宕机 调大 MaxMetaspaceSize、关闭多余动态代理
五级 堆外内存 OOM 文件 / IO 接口报错 限制文件大小、调高堆外内存上限

JVM 生产长期内存与 GC 调优规范

堆内存基础参数规范(Xms、Xmx、Xmn)

  1. -Xms:堆初始内存;-Xmx:堆最大堆内存 生产规范:两者设置相等 原因:运行时堆不会动态扩容 / 缩容,避免扩容触发额外 GC 停顿,性能更稳定。
  2. -Xmn:新生代总大小(Eden + 两个 Survivor) 经验分配:新生代占整个堆内存 1/3 ~ 1/4; 高并发接口、大量临时对象场景适度调大 Xmn,减少 Minor GC 频率。
  3. Eden 与 Survivor 默认比例 8:1:1 Eden 占新生代 80%,S0、S1 各 10%;保证复制算法备用区充足。

元空间 Metaspace 调优规范

  1. JDK8 无永久代,元空间使用本地堆外内存,默认无上限;
  2. 生产必须配置 -XX:MaxMetaspaceSize 限制最大值,防止无限占用操作系统内存;
  3. 频繁动态代理、反射、热更新项目,适当调高元空间上限;
  4. 尽量复用 Class、代理类,循环内禁止重复生成 CGLIB 动态类。

虚拟机栈参数 -Xss

  1. -Xss 控制单条线程栈内存大小;
  2. 默认一般 1M;递归业务、多层方法嵌套可适度调大;
  3. 线程数量极多的服务不能设置过大,会直接耗尽操作系统内存。

堆外直接内存规范

  1. 配置 -XX:MaxDirectMemorySize 限制 NIO 堆外缓冲区上限;
  2. DirectByteBuffer 使用完毕必须手动释放,不要依赖 GC 回收;
  3. 大文件上传、网络 IO 接口做分片处理,禁止一次性加载超大缓冲区。

对象生命周期编码规范(从根源减少 GC 与内存泄漏)

  1. 短期临时对象在方法内创建,方法执行结束自动销毁,不要存入全局静态集合;
  2. 全局缓存优先使用软引用 SoftReference、弱引用 WeakReference,内存不足自动释放;
  3. 禁止使用无限扩容静态 List/Map 存放业务数据(用户、订单、优惠券);
  4. 循环中避免频繁 new 大对象,抽取对象复用、使用对象池;
  5. 批量查询分页、分片读取,杜绝一次性加载百万级数据进内存。

GC 日志与故障快照配置(线上必开)

  1. 开启完整 GC 日志,记录每次 GC 耗时、内存变化、停顿时间;
  2. 配置 OOM 自动导出堆 dump 文件: -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/xxx/dump.hprof
  3. dump 文件用于离线 MAT 工具分析内存泄漏、大对象占用,无 dump 则 OOM 故障无法定位。

引用类型使用规范

  1. 普通业务实体:强引用,短期局部使用无问题;
  2. 缓存场景:优先软引用,内存紧张自动清理;
  3. 容器 key、临时映射:弱引用,避免内存泄漏;
  4. 堆外内存监控场景:虚引用,跟踪缓冲区回收。

递归与大对象规避规范

  1. 递归增加最大深度判断,防止 StackOverflowError;复杂递归改用循环实现;
  2. 禁止一次性创建超大数组、超大集合,拆分分批处理;
  3. 避免超大对象直接分配到老年代,频繁触发 Full GC。
调优维度 配置 / 编码规范 核心目的
堆内存 Xms/Xmx 数值保持一致 避免堆动态扩容产生额外 GC 停顿
新生代 - Xmn 占堆内存 1/3~1/4,高并发调大 减少 Eden 快速填满,降低 Minor GC 频率
元空间 MaxMetaspaceSize 设置固定上限 防止动态类耗尽本地内存,元空间 OOM
栈内存 - Xss 默认 1M,递归场景适度增大 避免栈溢出,多线程服务不宜过大
堆外内存 MaxDirectMemorySize 设置合理上限 限制 NIO 缓冲区占用,防止 Direct buffer OOM
代码对象管理 方法内创建临时对象,静态集合用软 / 弱引用 从根源杜绝内存泄漏,减少 Full GC
故障日志配置 开启 GC 日志、OOM 自动 dump 故障发生后可回溯定位内存问题
相关推荐
linux-hzh2 小时前
百日算法修炼 · Day 03
java·算法
互联网中的一颗神经元2 小时前
09 — .git 地图:打开那个隐藏文件夹
大数据·git·elasticsearch
嵌入式老牛3 小时前
三相电气量采集模块设计(三)非同步采样时的精度提升
算法·精度·计量
zyplayer-doc3 小时前
zyplayer-doc企业知识库能做什么:从文档创建、权限管理到AI问答的完整能力
大数据·javascript·数据库·人工智能·pdf·word
今天AI了吗4 小时前
精细化落地教程:TimechoAI调参标准+数据清洗规范+误差归因+阈值适配全维度指南
大数据·人工智能·算法
明源云5 小时前
资产管理软件哪个好?不动产资产管理系统的选型逻辑与标杆实践
大数据·人工智能·架构
zephyr055 小时前
从递归到迭代:二叉树非递归前中后序遍历详解
算法
Dr.kangder5 小时前
嵌入式总线设备解析——TTE总线应用与实践
开发语言·网络·算法·嵌入式·多任务·同步机制
Hi李耶5 小时前
【LeetCode】557.反转字符串中的单词 III
算法·leetcode·职场和发展
深蓝学院5 小时前
机器人学习算法五大体系详解:模仿、强化、多模态、持续学习……
算法·机器人