当前位置: 首页 > news >正文

虚幻GAS底层原理解剖九 (内存管理)

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 前言
  • 一、整体内存管理思路概览
  • 二、核心对象的生命周期与托管逻辑
    • UGameplayAbility 的管理
    • GameplayEffect 的内存管理
    • ActiveGameplayEffect 生命周期
  • 三、属性(Attribute)缓存与更新机制
  • 四、TargetData 与 EffectContext 的池化与复用
  • 五、网络同步中的内存优化
  • 六、对象池和自定义 Allocator 的应用
  • 七、垃圾回收与非 GC 对象管理
  • 总结:GAS 内存管理的关键设计点


前言

虚幻引擎中的 GAS(Gameplay Ability System) 是一个高性能、高扩展性的能力框架。为了支撑其复杂的技能、效果、属性和状态系统,它背后拥有一套精心设计的内存管理机制,包括:

  1. 结构体池化、对象复用
  2. 网络序列化内存优化
  3. 特定对象生命周期托管(Spec、Effect)
  4. 自定义 allocator、Arena 分配器
  5. Attribute 缓存机制
    子系统注册与 GC 管理

接下来我们分模块详细解析 GAS 是如何进行 内存管理和资源优化 的。

一、整体内存管理思路概览

GAS 的内存管理策略遵循以下原则:

原则举例
对象复用EffectSpecHandle、GameplayCueNotify
数据结构轻量化FGameplayAttributeData 只保存基础值与当前值
结构体池化目标数据、ModifierSpec 都来自池化内存
避免频繁GC能力实例只创建一次,Effect 不主动GC
引用计数管理GE 生命周期由 ASC 完整托管
Arena分配器属性聚合使用 FAggregator 特制 allocator

二、核心对象的生命周期与托管逻辑

UGameplayAbility 的管理

所有 Ability 的实例(C++/BP)在 GiveAbility() 时被构造并缓存

每个 FGameplayAbilitySpec 中持有指针

在技能激活时不会重新创建实例,而是复用

TSharedPtr<UGameplayAbility> AbilityInstance = Spec.GetPrimaryInstance();

内存只在注册或删除时分配一次。

GameplayEffect 的内存管理

所有 GE(UGameplayEffect)作为配置类,只读资源,常驻内存

每次应用 GE 时,并不会直接创建对象,而是构建轻量运行体:

FGameplayEffectSpecHandle SpecHandle = MakeOutgoingSpec(...);
FGameplayEffectSpec 是轻量结构体,仅含:
指向 GE 定义指针(不复制类)
捕获的属性快照(值类型)
一些标志位和引用类型(如 TargetData)

避免了 UE 常见 UObject 开销,支持池化。

ActiveGameplayEffect 生命周期

FActiveGameplayEffectsContainer ActiveGameplayEffects;

所有激活中的 GE 存放于此容器

GE 的添加/更新/移除由 ASC 内部完成

不暴露给外部直接操作(防止悬挂指针)

生命周期结束自动清除,不走垃圾回收(避免 GC 开销)

三、属性(Attribute)缓存与更新机制

每个属性是 FGameplayAttributeData,它只包含两个 float 值:

float BaseValue;
float CurrentValue;

所有属性更新通过 FAggregator 进行聚合处理:

// 聚合器计算路径
FAggregator → Mod Stack → Base + Add + Mult + Override → Current

特点:

  1. 聚合器使用轻量结构 + 内嵌 Arena Allocator
  2. 修改属性不触发对象创建,只更新浮点值
  3. 属性变化自动触发 NetDeltaSerialize,减少带宽与内存分配

四、TargetData 与 EffectContext 的池化与复用

FGameplayAbilityTargetDataHandle

  1. 用于传输目标信息的结构体

  2. 包含多个 FGameplayAbilityTargetData 派生类(如 TargetActorArray)

  3. 所有派生结构体均支持结构体序列化,无 UObject 开销

  4. 通过 TSharedPtr 管理生命周期(引用计数)

FGameplayEffectContextHandle

  1. 表示 GE 的施加上下文(来源 Actor、命中位置等)

  2. 内部指向 FGameplayEffectContext(非 UObject)

  3. 通过 TSharedPtr 管理,可嵌套复制

  4. 支持网络复制与再利用

这些都是 轻量非 UObject 结构体,避免 UE GC 开销

五、网络同步中的内存优化

GAS 中有两个重要的结构体用于同步:

结构体用途
FGameplayAttributeData属性同步(NetDeltaSerialize)
FActiveGameplayEffectHandle效果同步(GE ID + 生命周期)

优化机制:

  1. 使用 FastArraySerializer 同步 GE 列表,只同步变化项

  2. 所有同步数据支持 NetSerialize(),避免复制整个对象

  3. 使用 PackedBitWriter 实现高压缩的浮点数传输

  4. 不同步 UObject,只传递指针索引、标签、数值等

六、对象池和自定义 Allocator 的应用

GAS 使用了多种自定义分配器:

  1. 聚合器分配器 FAggregatorRef:
FGameplayEffectSpec::Captures → 聚合器系统 → ArenaAllocator

用于批量构建临时 Modifier 聚合数据,生命周期绑定到 GE Spec。

  1. GE 缓存:
    UGameplayEffect 被作为资源缓存,使用标准 UObject 生命周期,但不频繁加载/卸载。

  2. TagContainer:
    FGameplayTagContainer 使用值类型 + 显式引用共享,不走 UObject。

七、垃圾回收与非 GC 对象管理

GAS 中大量使用 非 UObject 的结构体 + 智能指针:

类型GC 管理方式
UGameplayAbility / GE常驻资源,由 ASC 或系统持有
FGameplayEffectSpec / TargetData非 GC 对象,TSharedPtr 管理
AttributeSetUObject,会注册到 ASC 的 SubObject 管理器中
GameplayCueNotify使用 Object Pool 缓存重用(如 FX)

总结:GAS 尽可能避开 GC,使用结构体和智能指针进行生命周期控制

总结:GAS 内存管理的关键设计点

设计点实现方式
复用对象,避免频繁创建技能/GE/特效对象仅实例化一次
尽量结构体化Spec/TargetData 均为结构体(TSharedPtr 管理)
避免 GC 压力除 Ability 外几乎无 UObject 生命周期
内存池化TargetData、Aggregator 使用 Arena 分配器
高效网络结构NetDeltaSerialize + PackedBitWriter
生命周期集中托管ASC 中统一管理技能/GE/属性/标签的状态
http://www.dtcms.com/a/321693.html

相关文章:

  • Jetpack Compose 主题系统全解析:从基础配置到动态切换
  • 商品、股指、ETF期权五档Tick分时历史行情数据解析
  • 数据库设计简述
  • Trae SOLO+ Holopix AI → “虚假广告“-鸠摩智转[特殊字符]割草小游戏
  • 【Unity3D实例-功能-跳跃】角色跳跃
  • Wan2.1-14B-T2V-FusionX-VACE本地部署教程:融合前沿技术,轻松掌握逼真物理模拟!
  • JAVA基础-NIO
  • 面向真实场景的定制化图像降质模型设计方案
  • 荣耀秋招启动
  • python---函数嵌套
  • 剑指offer第2版——面试题2:实现单例
  • 零知开源——基于STM32F103RBT6的TDS水质监测仪数据校准和ST7789显示实战教程
  • Windows ASLR 地址空间布局随机化技术详解
  • 连锁店管理系统的库存跟踪功能:数字化转型下的零售运营核心
  • VR 设备 PCB 怎样凭借高频材料达成高速传输
  • [激光原理与应用-185]:光学器件 - BBO、LBO、CLBO晶体的全面比较
  • (1-9-2)Java 工厂模式
  • 基于AI多模态数据分析:美国劳动力市场疲软信号识别与趋势预测
  • 塑料可回收物检测数据集-10,000 张图片 智能垃圾分类系统 环保回收自动化 智慧城市环卫管理 企业环保合规检测 教育环保宣传 供应链包装优化
  • Neo4j APOC插件安装教程
  • 学生如何使用 DeepSeek 帮助自己的学习?
  • 【具身智能】具身智能的革命——人形机器人如何重塑人类日常生活
  • Go语言的gRPC教程-超时控制
  • XXL-JOB多实例
  • 「ECG信号处理——(22)Pan-Tompkins Findpeak 阈值检测 差分阈值算法——三种R波检测算法对比分析」2025年8月8日
  • 宁商平台税务新政再升级:精准施策,共筑金融投资新生态
  • 创建MyBatis-Plus版的后端查询项目
  • 构网型逆变器三相共直流母线式光储VSG仿真模型【simulink实现】
  • 影刀 —— 练习 —— 读取Excel的AB两列组成字典
  • 【数值积分】如何利用梯形法则近似求解积分