UE4内存池浅谈

前言

作为一款超重量级的游戏引擎,Unreal Engine在提升效率和效果方面做了全面的尝试,内存池这种关乎效率的关键基础设施也不例外。为最大化的适应自己的特点,UE针对内存池做足了探索和优化。
总体而言,UE4的内存统一由FMemory来管理,但其内存分配策略确有多种方式。下表中罗列了UE4中的内存分配器。

序号 分配器 描述
1 Ansi 默认使用的c语言分配器
2 Stomp check for memory stomping
3 TBB Intel TBB, default for Windows
4 Jemalloc FreeBSD malloc
5 malloc Linux默认
6 Binned 一代装箱式内存分配器
7 Binned2 二代装箱内存分配器
8 Binned3 三代装箱内存分配器
9 Platform 平台自定义

上述分配器体现在枚举EMemoryAllocatorToUse中,如下:

enum EMemoryAllocatorToUse
{
    Ansi, 
    Stomp,
    TBB,
    Jemalloc,
    malloc,
    Binned,
    Binned2,
    Binned3,
    Platform,
};

上述9种分配器中,Binned1/2/3显然是Unreal自己设计开发的,笔者曾在嵌入式Linux(非Android)平台上使用过Unreal,其时采用的正式Binned2分配器。
因此本文首先从Binned系列的分配器开始讲起。

Binned分配器介绍

得名原因

Binned得名于Bin,主要有两个含义:
存储容器:"bin"可以指一个用于存放物品的容器,比如垃圾桶或者储物箱。这是"bin"最常见的含义之一,指的是一个可以存放、分类或暂时保存物品的空间

分组或分类:在数据处理和统计学领域,“bin"也可以指将数据分组到特定的类别或区间的过程。例如,在进行频率分布分析时,数据点会被"binned”(分组)到不同的区间或箱子中,以便于分析和解释数据

于我们而言,两个含义没有什么大不同,Binned我们大可以就叫做分箱式内存分配,或者分组式内存分配。

在Binned一代中,内存分配器只管理小块内存,大块内存直接扔给OS去处理。而一代中,小块内存正是采用预分配从16B到32K一系列大小不等的bin的方法,在申请时直接找出刚好够用的bin,从这个bin的Pool中一个Block分出去。
当然,上述的描述并不严谨,比如某个大小的bin的Pool并不仅有一个,分完了就没了。

    游戏引擎中之所以要做内存管理,一个是加快内存分配速度,另一个就是处理内存泄漏问题。     1.先简单说处理内存泄漏这个问题,一般的引擎在debug 模式下 都有一个记录内存分配的结构体,每分配一段内存就记录这段内存的信息,包括大小,分配时间,是否是数组,前后越界的标记等等吧,其实这些都不是那么重要,因为你只知道这些,一旦泄漏出现,你虽然知道泄漏,但无法定位。相反如果你知道堆栈的调用信息,就能准确定位。我以前的实现,在debug下,只记录当前调用new的时候的行号和文件,也就是内部的__FILE__ __LINE___.。我看了同事那个能记录堆栈调用过程,简直觉得很牛逼(其实不是调用堆栈,只是打印出调用过程,继续往下看你就知道了),以前自己也想过,但不知道怎么去实现。如果U3里面也加入这个功能,那就更牛叉了。思想很简单,就是核心东西在一个函数,这个是系统函数,提供当前这行指令所在的地址,它会打印出来这行指令的文件名和行号。先详细说下数据在内存的分配     最早的计算机数据段和代码段区分的很严格,现在似乎没有这么严格了!对于全局变量和静态变量它的分配完全在数据段分配,知道运行结束才会收回内存!而对于自动变量(包括函数参数和函数中定义的变量)则在堆栈中分配!一般的分配情形是这样的:从栈下到栈顶依次是函数参数,函数结束后下一条指令的地址,寄存器保护,然后是函数中定义的变量!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值