游戏开发57课 性能优化14

news2024/10/6 22:20:33

 

5. 内存优化

内存优化目的是加快IO,防止卡主线程,防止频繁操作(创建/删除)内存,避免内存碎片化和占用过高。

5.1 缓存法

与CPU的缓存计算类似,思路是将需要重复创建的对象缓存起来,销毁时将它放入缓存列表,再次创建时优先从缓存列表中读取。实现伪代码:

Array<Object> _objectCache;

Object CreateObject()
{
    // 先尝试从缓存中获取对象
    if (_objectCache.size() > 0)
    {
        return _objectCache.pop_back();
    }
    return new Object();
}

void DestroyObject(Object obj)
{
    _objectCache.push_back(obj); // 删除时将其放入缓存列表。
}

缓存法可以降低内存的创建/删除频率,避免碎片化。常用于数量多且创建频繁的物体,如小兵,NPC,血条,特效,道具,各类图标等等。

5.2 内存池

内存池技术是现代主流引擎的标配,目的是避免内存碎片化,加速内存分配和管理。实现思想通常是由引擎预先创建一块较大的内存(也可动态调整),这块内存通过有效的数据结构和算法策略,统一管理小块内存的分配和回收,并为逻辑层提供内存相关的操作接口。内存池实现的方式很多,各有优劣,不一而足。下图是其中的一种实现方式:

分配的内存分为四个部分:第1部分是内存池结构体信息;第2部分是内存映射表;第3部分是内存Chunk缓冲区;第4部分是可分配内存区。更多参看这里。

5.3 资源管理器

资源管理器是将所有需要用到的文件资源统一管理起来,统一创建,加载,释放,回收等,为的是提高复用率,减少资源冗余和内存开销,也是现代引擎必备的一个模块。假如没有资源管理器,势必会造成资源的冗余,同一份资源可能存在很多份内存数据(下图)。

上图所示中,每个模型(Model)引用了一份网格(Mesh)内存数据,3个模型实例就有3份Mesh内存数据,造成Mesh内存资源的冗余。而有了资源管理器的统一管理,所有引用到文件资源的实例都指向了同一份内存数据(下图),避免了内存资源冗余,降低内存和IO消耗。

资源管理器的实现比较简单,主要是运用模板将物体类型抽象出来,然后每个物体类型用一个map<filePath, objectData>的表存储。具体实现这里不累述。

5.4 控制GC

GC是Garbage Collect的简称,意为垃圾回收,是游戏引擎中采用一定策略回收内存池或托管堆里的无用内存和缓存区无用对象的一种技术。GC机制就是防止内存占用过多过久,是一种自动调节内存占用的常用技法。GC的触发一般分为两种:

  • 引擎触发。一般是时间间隔到了,或者内存占有量到了某个阈值,引擎便会触发GC。
  • 用户调用。通常引擎也提供了API给游戏应用,以便逻辑层可以控制GC的时机。例如Unity的GC.Collect()接口可以触发GC操作。

但是触发GC需要遍历内存池/托管堆/各类缓存表,还可能引发内存碎片整理操作,所以它需要耗费一定的CPU性能,是引起掉帧和卡顿的罪魁祸首之一。那么,我们就需要在逻辑层采用一些方法,避免触发GC,或者减少触发GC的处理时间。常用的方法:

  • 避免频繁创建/删除。这个好理解,频繁创建删除对象,会引起很多内存碎片和无用对象,增加触发GC的几率和时间。
  • 帧更新内尽量避免临时对象和创建内存。
  • for/while等循环内避免避免临时对象和创建内存。
  • 尽量避免申请大块内存。申请大块内存会导致内存暴涨,提升GC的几率。
  • 避免内存泄漏。这个需要每个技术人员的职业技能和觉悟,也可以通过一些辅助工具检查内存泄漏,详见1.3。
  • 主动调用GC。比如在进入战斗前后,切换场景前后,切换主要界面前后调用GC,可以一定程度上减少内存占用,避免掉帧/卡顿。

5.5 逻辑优化

逻辑优化的目标是尽量避免无用的内存操作,防止内存泄漏,尽快释放内存,减少全局变量的使用,关注第三方库的内存消耗。

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

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

相关文章

安装、启动与停止Apache服务

安装、启动与停止Apache服务 安装Apache相关软件 [rootcentos7 ~]# rpm -q httpd [rootcentos7-1 ~]# mkdir /opt/centos //创建目录/opt/centos [rootcentos7-1 ~]# mount /dev/cdrom /opt/centos //挂载光盘到/opt/centos 下 mount: /dev/sr0 写保护…

Spring Boot 3.0.0正式发布,Banner不再支持图片增强可观测性

本文已被https://yourbatman.cn收录&#xff1b;女娲Knife-Initializr工程可公开访问啦&#xff1b;程序员专用网盘https://wangpan.yourbatman.cn&#xff1b;技术专栏源代码大本营&#xff1a;https://github.com/yourbatman/tech-column-learning&#xff1b;公号后台回复“…

openCV(一)基础背景

1 认识计算机视觉 2012年AlexNet模型在ImageNet图像分类中获得比赛冠军&#xff0c;深度学习开始在计算机视觉领域流行。早期的计算机视觉主要集中在重建方面&#xff0c;2012年以后在感知和重建两个领域都受到了深度学习的影响。应用场景包括自动驾驶、机器视觉、安防监控、其…

猿如意中的【PostgreSQL 数据库】工具详情介绍

猿如意中的【PostgreSQL 数据库】工具详情介绍 一、工具名称 PostgreSQL 数据库 二、下载安装渠道 PostgreSQL 数据库V14.2 通过CSDN官方开发的【猿如意】客户端进行下载安装。 2.1 什么是猿如意&#xff1f; 猿如意是一款面向开发者的辅助开发工具箱&#xff0c;包含了效…

jenkins-pipeline与变量

本文介绍如何在pipeline中使用变量 使用jenkins预定义的环境变量 jenkins预先定义了一些环境变量&#xff0c;在pipeline中使用${env.key}来调用 另外安装了第三方插件&#xff0c;会有新的环境变量&#xff0c;可以使用插件Environment Inject来查看 在pipeline中使用预定义…

Java二维数组项目练习

T1.显示所有书店客户的信息 示例代码 public static void main(String[] args) {String[][] users{{"1100","18","100"},{"1101","24","834"},{"1102","13","20000"},{"1103…

软件测试——用例篇

文章目录为什么在测试前要设计测试用例基于需求设计测试用例等价类边界值错误猜测法场景法因果图正交法为什么在测试前要设计测试用例 测试用例是执行测试的依据。可以复用&#xff08;回归测试的时候&#xff09;衡量需求的覆盖率自动化测试的依据有借鉴意义&#xff0c;后续…

OH----原子量的妙用--保护usb时序

1、问题&#xff1a; 展锐平台&#xff0c;usb otg高概率不能正确检测识别到 2、思路&#xff1a; usb使用musb控制器&#xff0c;展锐的平台处理代码是musb_sprd.c&#xff0c;在这个文件中对usb mode做检测和切换&#xff0c;log级别跳到最高&#xff0c;在probe中的关键函…

用 Taichi 加速 Python:提速 100+ 倍!

Python 已经成为世界上最流行的编程语言&#xff0c;尤其在深度学习、数据科学等领域占据主导地位。但是由于其解释执行的属性&#xff0c;Python 较低的性能很影响它在计算密集&#xff08;比如多重 for 循环&#xff09;的场景下发挥作用&#xff0c;实在让人又爱又恨。如果你…

PAT(乙级)2022年冬季考试

此前先后花了十元去做了乙级题&#xff0c;从最开始分别是70&#xff0c;35&#xff0c;43&#xff0c;33&#xff08;途中做了RobpCom,只搞定了签到题&#xff09;&#xff0c;想着报今年的冬季赛&#xff0c;但是报名费有点高啊&#xff0c;加上做下来感觉不怎么样&#xff0…

[附源码]Python计算机毕业设计Django的黄河文化科普网站

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…

GitHub搜索开源项目

GitHub的流行&#xff0c; GitHub在开源世界的受欢迎程度自不必多言。再加上今天&#xff0c;GitHub官方又搞了个大新闻&#xff1a;私有仓库也改为免费使用&#xff0c;这在原来可是需要真金白银的买的。可见微软收购后&#xff0c;依然没有改变 GitHub 的定位&#xff0c;甚至…

使用高德地图展示点位和信息窗体展示数据及播放视频

使用高德地图做了一个在地图展示点位&#xff0c;并通过点击&#xff0c;显示直播的功能&#xff0c;这个任务是为了之后大屏做准备。 这是一个能展示多个点标记&#xff0c;并在点击的时候弹出信息窗体&#xff0c;并在信息窗体中播放视频&#xff0c;且展示相关信息以及操作…

【Lilishop商城】No3-6.模块详细设计,商品模块-2(商品及强关联附属 商品sku、批发、图册等等)的详细设计

仅涉及后端&#xff0c;全部目录看顶部专栏&#xff0c;代码、文档、接口路径在&#xff1a; 【Lilishop商城】记录一下B2B2C商城系统学习笔记~_清晨敲代码的博客-CSDN博客 全篇会结合业务介绍重点设计逻辑&#xff0c;其中重点包括接口类、业务类&#xff0c;具体的结合源代码…

队列的练习题

用队列实现栈 请你仅使用两个队列实现一个后入先出&#xff08;LIFO&#xff09;的栈&#xff0c;并支持普通栈的全部四种操作&#xff08;push、top、pop 和 empty&#xff09; 实现 MyStack 类&#xff1a; void push(int x) 将元素 x 压入栈顶int pop()移除并返回栈顶元素…

I2C总线式驱动开发

文章目录前言一、Linux内核对I2C总线的支持1.1、理解I2C设备驱动、I2C总线驱动以及I2C核心之间的关系1.2、i2c二级外设驱动开发涉及到核心结构体及其相关接口函数&#xff1a;二、I2C总线二级外设驱动开发方法-名称匹配2.1、i2c二级外设client框架&#xff1a;2.2、i2c二级外设…

[附源码]Nodejs计算机毕业设计基于java网上心理咨询系统数据分析Express(程序+LW)

该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程。欢迎交流 项目运行 环境配置&#xff1a; Node.js Vscode Mysql5.7 HBuilderXNavicat11VueExpress。 项目技术&#xff1a; Express框架 Node.js Vue 等等组成&#xff0c;B/S模式 Vscode管理前后端分…

Docker整体架构及底层通信原理简述

Docker 是一个 C/S 模式的架构&#xff0c;后端是一个松耦合架构&#xff0c;众多模块各司其职。 Docker运行的基本流程为&#xff1a; 1. 用户是使用Docker Client与Docker Deamon建立通信&#xff0c;并发送请求给后者&#xff1b; 2.Docker Deamon作为Docker架构中的主体…

复制项目配准信息,用于将超级大图贴到地图上

目录 1 前言 2 大图片另存为一个小图片&#xff0c;小图片文件名包含坐标参数 3 制作第二个普通配准项目&#xff0c;原来的大图不能用坐标信息命名 4 开始配准切图 1 前言 前面介绍过&#xff0c;如果已经知道一幅图片的任意2个角的坐标&#xff0c;可以用非常简单的方式…

Spring Bean的初始化过程 initializeBean

目录 1.定义对象 2.注册对象 3.DEBUG Aware处理 4.完整初始化流程概览 5. applyBeanPostProcessorsBeforeInitialization 5.1 this.beanPostProcessors 里面的处理顺序 5.1.1 ApplicationContextAwareProcessor 5.1.2 ApplicationListenerDetector 5.1.3 WebApplicatio…