mirror of
https://github.com/GeWuYou/GFramework.git
synced 2026-03-24 20:34:29 +08:00
- 将标题从"架构模式最佳实践"改为"架构设计模式指南" - 添加全面的架构设计模式介绍和概述 - 新增MVC模式详细说明,包括概念、GFramework实现示例和最佳实践 - 新增MVVM模式详细说明,包括概念、GFramework实现示例和最佳实践 - 新增命令模式详细说明,包括概念、实现示例和撤销功能支持 - 新增查询模式详细说明,包括CQRS概念和复杂查询示例 - 新增事件驱动模式详细说明,包括事件定义和监听实现 - 新增依赖注入模式详细说明,包括构造函数注入示例 - 新增服务定位器模式详细说明,包括与依赖注入对比 - 新增对象池模式详细说明,包括通用对象池实现 - 新增状态模式详细说明,包括异步状态和状态机系统 - 补充模式选择与组合建议,针对小型、中型、大型项目提供不同方案 - 更新代码示例中的泛型语法格式,统一使用尖括号表示法
385 lines
10 KiB
Markdown
385 lines
10 KiB
Markdown
---
|
||
title: 移动平台优化指南
|
||
description: 针对移动平台的性能优化、内存管理和电池优化最佳实践
|
||
---
|
||
|
||
# 移动平台优化指南
|
||
|
||
## 概述
|
||
|
||
移动平台游戏开发面临着独特的挑战:有限的内存、较弱的处理器、电池续航限制、触摸输入、多样的屏幕尺寸等。本指南将帮助你使用
|
||
GFramework 开发高性能的移动游戏,提供针对性的优化策略和最佳实践。
|
||
|
||
**移动平台的主要限制**:
|
||
|
||
- **内存限制**:移动设备内存通常在 2-8GB,远低于 PC
|
||
- **CPU 性能**:移动 CPU 性能较弱,且受热量限制
|
||
- **GPU 性能**:移动 GPU 功能有限,填充率和带宽受限
|
||
- **电池续航**:高性能运行会快速消耗电池
|
||
- **存储空间**:应用包大小受限,用户存储空间有限
|
||
- **网络环境**:移动网络不稳定,延迟较高
|
||
|
||
**优化目标**:
|
||
|
||
- 减少内存占用(目标:<200MB)
|
||
- 降低 CPU 使用率(目标:<30%)
|
||
- 优化 GPU 渲染(目标:60 FPS)
|
||
- 延长电池续航(目标:3+ 小时)
|
||
- 减小包体大小(目标:<100MB)
|
||
|
||
## 核心概念
|
||
|
||
### 1. 内存管理
|
||
|
||
移动设备内存有限,需要精细管理:
|
||
|
||
```csharp
|
||
// 监控内存使用
|
||
public class MemoryMonitor : AbstractSystem
|
||
{
|
||
private const long MemoryWarningThreshold = 150 * 1024 * 1024; // 150MB
|
||
private const long MemoryCriticalThreshold = 200 * 1024 * 1024; // 200MB
|
||
|
||
protected override void OnInit()
|
||
{
|
||
this.RegisterEvent<GameUpdateEvent>(OnUpdate);
|
||
}
|
||
|
||
private void OnUpdate(GameUpdateEvent e)
|
||
{
|
||
// 每 5 秒检查一次内存
|
||
if (e.TotalTime % 5.0 < e.DeltaTime)
|
||
{
|
||
CheckMemoryUsage();
|
||
}
|
||
}
|
||
|
||
private void CheckMemoryUsage()
|
||
{
|
||
var memoryUsage = GC.GetTotalMemory(false);
|
||
|
||
if (memoryUsage > MemoryCriticalThreshold)
|
||
{
|
||
// 内存严重不足,强制清理
|
||
SendEvent(new MemoryCriticalEvent());
|
||
ForceMemoryCleanup();
|
||
}
|
||
else if (memoryUsage > MemoryWarningThreshold)
|
||
{
|
||
// 内存警告,温和清理
|
||
SendEvent(new MemoryWarningEvent());
|
||
SoftMemoryCleanup();
|
||
}
|
||
}
|
||
|
||
private void ForceMemoryCleanup()
|
||
{
|
||
// 卸载不必要的资源
|
||
var resourceManager = this.GetUtility<IResourceManager>();
|
||
resourceManager.UnloadUnusedResources();
|
||
|
||
// 清理对象池
|
||
var poolSystem = this.GetSystem<ObjectPoolSystem>();
|
||
poolSystem.TrimPools();
|
||
|
||
// 强制 GC
|
||
GC.Collect();
|
||
GC.WaitForPendingFinalizers();
|
||
GC.Collect();
|
||
}
|
||
|
||
private void SoftMemoryCleanup()
|
||
{
|
||
// 温和清理:只清理明确不需要的资源
|
||
var resourceManager = this.GetUtility<IResourceManager>();
|
||
resourceManager.UnloadUnusedResources();
|
||
}
|
||
}
|
||
```
|
||
|
||
### 2. 性能分析
|
||
|
||
使用性能分析工具识别瓶颈:
|
||
|
||
```csharp
|
||
public class PerformanceProfiler : AbstractSystem
|
||
{
|
||
private readonly Dictionary<string, PerformanceMetrics> _metrics = new();
|
||
|
||
public IDisposable Profile(string name)
|
||
{
|
||
return new ProfileScope(name, this);
|
||
}
|
||
|
||
private void RecordMetric(string name, double duration)
|
||
{
|
||
if (!_metrics.TryGetValue(name, out var metrics))
|
||
{
|
||
metrics = new PerformanceMetrics();
|
||
_metrics[name] = metrics;
|
||
}
|
||
|
||
metrics.AddSample(duration);
|
||
}
|
||
|
||
public void PrintReport()
|
||
{
|
||
Console.WriteLine("\n=== 性能报告 ===");
|
||
foreach (var (name, metrics) in _metrics.OrderByDescending(x => x.Value.AverageMs))
|
||
{
|
||
Console.WriteLine($"{name}:");
|
||
Console.WriteLine($" 平均: {metrics.AverageMs:F2}ms");
|
||
Console.WriteLine($" 最大: {metrics.MaxMs:F2}ms");
|
||
Console.WriteLine($" 最小: {metrics.MinMs:F2}ms");
|
||
Console.WriteLine($" 调用次数: {metrics.SampleCount}");
|
||
}
|
||
}
|
||
|
||
private class ProfileScope : IDisposable
|
||
{
|
||
private readonly string _name;
|
||
private readonly PerformanceProfiler _profiler;
|
||
private readonly Stopwatch _stopwatch;
|
||
|
||
public ProfileScope(string name, PerformanceProfiler profiler)
|
||
{
|
||
_name = name;
|
||
_profiler = profiler;
|
||
_stopwatch = Stopwatch.StartNew();
|
||
}
|
||
|
||
public void Dispose()
|
||
{
|
||
_stopwatch.Stop();
|
||
_profiler.RecordMetric(_name, _stopwatch.Elapsed.TotalMilliseconds);
|
||
}
|
||
}
|
||
}
|
||
|
||
// 使用示例
|
||
public class GameSystem : AbstractSystem
|
||
{
|
||
private PerformanceProfiler _profiler;
|
||
|
||
protected override void OnInit()
|
||
{
|
||
_profiler = this.GetSystem<PerformanceProfiler>();
|
||
}
|
||
|
||
private void UpdateGame()
|
||
{
|
||
using (_profiler.Profile("GameUpdate"))
|
||
{
|
||
// 游戏更新逻辑
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
### 3. 电池优化
|
||
|
||
减少不必要的计算和渲染:
|
||
|
||
```csharp
|
||
public class PowerSavingSystem : AbstractSystem
|
||
{
|
||
private bool _isPowerSavingMode;
|
||
private int _targetFrameRate = 60;
|
||
|
||
protected override void OnInit()
|
||
{
|
||
this.RegisterEvent<BatteryLowEvent>(OnBatteryLow);
|
||
this.RegisterEvent<BatteryNormalEvent>(OnBatteryNormal);
|
||
}
|
||
|
||
private void OnBatteryLow(BatteryLowEvent e)
|
||
{
|
||
EnablePowerSavingMode();
|
||
}
|
||
|
||
private void OnBatteryNormal(BatteryNormalEvent e)
|
||
{
|
||
DisablePowerSavingMode();
|
||
}
|
||
|
||
private void EnablePowerSavingMode()
|
||
{
|
||
_isPowerSavingMode = true;
|
||
|
||
// 降低帧率
|
||
_targetFrameRate = 30;
|
||
Application.targetFrameRate = _targetFrameRate;
|
||
|
||
// 降低渲染质量
|
||
QualitySettings.SetQualityLevel(0);
|
||
|
||
// 减少粒子效果
|
||
SendEvent(new ReduceEffectsEvent());
|
||
|
||
// 暂停非关键系统
|
||
PauseNonCriticalSystems();
|
||
|
||
Console.WriteLine("省电模式已启用");
|
||
}
|
||
|
||
private void DisablePowerSavingMode()
|
||
{
|
||
_isPowerSavingMode = false;
|
||
|
||
// 恢复帧率
|
||
_targetFrameRate = 60;
|
||
Application.targetFrameRate = _targetFrameRate;
|
||
|
||
// 恢复渲染质量
|
||
QualitySettings.SetQualityLevel(2);
|
||
|
||
// 恢复粒子效果
|
||
SendEvent(new RestoreEffectsEvent());
|
||
|
||
// 恢复非关键系统
|
||
ResumeNonCriticalSystems();
|
||
|
||
Console.WriteLine("省电模式已禁用");
|
||
}
|
||
|
||
private void PauseNonCriticalSystems()
|
||
{
|
||
// 暂停动画系统
|
||
var animationSystem = this.GetSystem<AnimationSystem>();
|
||
animationSystem?.Pause();
|
||
|
||
// 暂停音效系统(保留音乐)
|
||
var audioSystem = this.GetSystem<AudioSystem>();
|
||
audioSystem?.PauseSoundEffects();
|
||
}
|
||
|
||
private void ResumeNonCriticalSystems()
|
||
{
|
||
var animationSystem = this.GetSystem<AnimationSystem>();
|
||
animationSystem?.Resume();
|
||
|
||
var audioSystem = this.GetSystem<AudioSystem>();
|
||
audioSystem?.ResumeSoundEffects();
|
||
}
|
||
}
|
||
```
|
||
|
||
## 内存优化
|
||
|
||
### 1. 资源管理策略
|
||
|
||
实现智能资源加载和卸载:
|
||
|
||
```csharp
|
||
public class MobileResourceManager : AbstractSystem
|
||
{
|
||
private readonly IResourceManager _resourceManager;
|
||
private readonly Dictionary<string, ResourcePriority> _resourcePriorities = new();
|
||
private readonly HashSet<string> _loadedResources = new();
|
||
|
||
public MobileResourceManager(IResourceManager resourceManager)
|
||
{
|
||
_resourceManager = resourceManager;
|
||
}
|
||
|
||
protected override void OnInit()
|
||
{
|
||
// 配置资源优先级
|
||
ConfigureResourcePriorities();
|
||
|
||
// 监听场景切换事件
|
||
this.RegisterEvent<SceneChangedEvent>(OnSceneChanged);
|
||
|
||
// 监听内存警告
|
||
this.RegisterEvent<MemoryWarningEvent>(OnMemoryWarning);
|
||
}
|
||
|
||
private void ConfigureResourcePriorities()
|
||
{
|
||
// 高优先级:UI、玩家资源
|
||
_resourcePriorities["ui/"] = ResourcePriority.High;
|
||
_resourcePriorities["player/"] = ResourcePriority.High;
|
||
|
||
// 中优先级:敌人、道具
|
||
_resourcePriorities["enemy/"] = ResourcePriority.Medium;
|
||
_resourcePriorities["item/"] = ResourcePriority.Medium;
|
||
|
||
// 低优先级:特效、装饰
|
||
_resourcePriorities["effect/"] = ResourcePriority.Low;
|
||
_resourcePriorities["decoration/"] = ResourcePriority.Low;
|
||
}
|
||
|
||
public async Task<T> LoadResourceAsync<T>(string path) where T : class
|
||
{
|
||
// 检查内存
|
||
if (IsMemoryLow())
|
||
{
|
||
// 内存不足,先清理低优先级资源
|
||
UnloadLowPriorityResources();
|
||
}
|
||
|
||
var resource = await _resourceManager.LoadAsync<T>(path);
|
||
_loadedResources.Add(path);
|
||
|
||
return resource;
|
||
}
|
||
|
||
private void OnSceneChanged(SceneChangedEvent e)
|
||
{
|
||
// 场景切换时,卸载旧场景资源
|
||
UnloadSceneResources(e.PreviousScene);
|
||
|
||
// 预加载新场景资源
|
||
PreloadSceneResources(e.NewScene);
|
||
}
|
||
|
||
private void OnMemoryWarning(MemoryWarningEvent e)
|
||
{
|
||
// 内存警告,卸载低优先级资源
|
||
UnloadLowPriorityResources();
|
||
}
|
||
|
||
private void UnloadLowPriorityResources()
|
||
{
|
||
var resourcesToUnload = _loadedResources
|
||
.Where(path => GetResourcePriority(path) == ResourcePriority.Low)
|
||
.ToList();
|
||
|
||
foreach (var path in resourcesToUnload)
|
||
{
|
||
_resourceManager.Unload(path);
|
||
_loadedResources.Remove(path);
|
||
}
|
||
|
||
Console.WriteLine($"卸载了 {resourcesToUnload.Count} 个低优先级资源");
|
||
}
|
||
|
||
private ResourcePriority GetResourcePriority(string path)
|
||
{
|
||
foreach (var (prefix, priority) in _resourcePriorities)
|
||
{
|
||
if (path.StartsWith(prefix))
|
||
return priority;
|
||
}
|
||
|
||
return ResourcePriority.Medium;
|
||
}
|
||
|
||
private bool IsMemoryLow()
|
||
{
|
||
var memoryUsage = GC.GetTotalMemory(false);
|
||
return memoryUsage > 150 * 1024 * 1024; // 150MB
|
||
}
|
||
}
|
||
|
||
public enum ResourcePriority
|
||
{
|
||
Low,
|
||
Medium,
|
||
High
|
||
}
|
||
```
|
||
|
||
### 2. 纹理压缩和优化
|
||
|