美文网首页
12 UE5 内存分配器Allocator介绍

12 UE5 内存分配器Allocator介绍

作者: 游戏开发程序员 | 来源:发表于2024-02-23 21:55 被阅读0次

    内存分配器Allocator

    • 容器都依赖一个分配器,扩容和回收内存都通过分配器实现
    • 分配器是负责封装内存管理的对象]
    • 标准库STL容器使用它们来管理容器内部的所有内存分配
    • 动机是使容器完全独立于底层内存模型
    • 让程序员控制容器内的内存分配,而不是用底层硬件的地址模型

    TAllocatorTraitsBase

    • 定义了一些特性
    template <typename AllocatorType>
    struct TAllocatorTraitsBase
    {
        enum { IsZeroConstruct           = false };
        enum { SupportsFreezeMemoryImage = false };
        enum { SupportsElementAlignment  = false };
    };
    

    ContainerAllocationPolicies.h 接口类定义

    • 接口类 说明内存分配器是需要实现那些接口
    • 基础类型,他们的大小和内存占用是一致的,而结构体sizeof可能会大于成员大小总和.
    • 使用了内存对齐:让数据读取更高效,有些平台不对齐会崩溃
    class FContainerAllocatorInterface
    {
    public:
        using SizeType = int32;
    
        enum { NeedsElementType = true };
    
        enum { RequireRangeCheck = true };
    
        //  A class that receives both the explicit allocation and implicit 
        template<typename ElementType>
        class ForElementType
        {
            void MoveToEmpty(ForElementType& Other);
    
            // 需要明确类型 ElementType
            template <typename OtherAllocatorType>
            void MoveToEmptyFromOtherAllocator(typename OtherAllocatorType::template ForElementType<ElementType>& Other);
    
            ElementType* GetAllocation() const;
    
            // NumBytesPerElement - The number of bytes/element.
            void ResizeAllocation(
                SizeType PreviousNumElements, SizeType NumElements, SIZE_T NumBytesPerElement);
      
                   // exists SupportsElementAlignment == true 类似的重载函数就不列出
            void ResizeAllocation(SizeType PreviousNumElements,SizeType NumElements,SIZE_T NumBytesPerElement,
    uint32 AlignmentOfElement);
    
            SizeType CalculateSlackReserve(
                SizeType NumElements,SIZE_T NumBytesPerElement) const;
    
            SizeType CalculateSlackShrink(
                SizeType NumElements,   SizeType CurrentNumSlackElements,SIZE_T NumBytesPerElement) const;
    
            SizeType CalculateSlackGrow(
                SizeType NumElements,   SizeType CurrentNumSlackElements,SIZE_T NumBytesPerElement) const;
    
            SIZE_T GetAllocatedSize(SizeType NumAllocatedElements, SIZE_T NumBytesPerElement) const;
    
            bool HasAllocation() const;
    
            SizeType GetInitialCapacity() const;
        };
    
        // NeedsElementType=false 时使用
        typedef ForElementType<FScriptContainerElement> ForAnyElementType;
    };
    
    

    实现的内存分配器

    // 对一些默认分配器的定义
    template <int IndexSize> class TSizedDefaultAllocator : public TSizedHeapAllocator<IndexSize> 
    { public: typedef TSizedHeapAllocator<IndexSize> Typedef; };
    
    template<int IndexSize> class TSizedDefaultAllocator;
    using FDefaultAllocator = TSizedDefaultAllocator<32>;
    
    using FHeapAllocator = TSizedHeapAllocator<32>;
    
    template <uint32 NumInlineElements, typename SecondaryAllocator = FDefaultAllocator>
    using TInlineAllocator = TSizedInlineAllocator<NumInlineElements, 32, SecondaryAllocator>;
    template <uint32 NumInlineElements, typename SecondaryAllocator = FDefaultAllocator64>
    using TInlineAllocator64 = TSizedInlineAllocator<NumInlineElements, 64, SecondaryAllocator>;
    
    

    UE的容器用的分配器定义

    • TSizedDefaultAllocator 继承 TSizedHeapAllocator
    • using FDefaultAllocator = TSizedDefaultAllocator<32>;
    • FString = FDefaultAllocator
    • TArray TSortedMap = FDefaultAllocator
    • TSet TMap TMultiMap = FDefaultSetAllocator
    /// @cond DOXYGEN_WARNINGS
    template<int IndexSize> class TSizedDefaultAllocator;
    using FDefaultAllocator = TSizedDefaultAllocator<32>;
    using FDefaultAllocator64 = TSizedDefaultAllocator<64>;
    class FDefaultSetAllocator;
    
    class FString;
    
    template<> struct TIsContiguousContainer<FString> { static constexpr bool Value = true; };
    
    template<typename T, typename Allocator = FDefaultAllocator> class TArray;
    template<typename T> using TArray64 = TArray<T, FDefaultAllocator64>;
    template<typename T, typename SizeType = int32> class TArrayView;
    template<typename T> using TArrayView64 = TArrayView<T, int64>;
    template<typename T, typename SizeType = int32> using TConstArrayView = TArrayView<const T, SizeType>;
    template<typename T> using TConstArrayView64 = TConstArrayView<T, int64>;
    template<typename T> class TTransArray;
    template<typename InKeyType, typename InValueType, bool bInAllowDuplicateKeys> struct TDefaultMapHashableKeyFuncs;
    template<typename InKeyType, typename InValueType, typename SetAllocator = FDefaultSetAllocator, typename KeyFuncs = TDefaultMapHashableKeyFuncs<InKeyType, InValueType, false> > class TMap;
    template<typename KeyType, typename ValueType, typename SetAllocator = FDefaultSetAllocator, typename KeyFuncs = TDefaultMapHashableKeyFuncs<KeyType, ValueType, true > > class TMultiMap;
    template <typename T = void > struct TLess;
    template <typename> struct TTypeTraits;
    template<typename InKeyType, typename InValueType, typename ArrayAllocator = FDefaultAllocator, typename SortPredicate = TLess<typename TTypeTraits<InKeyType>::ConstPointerType> > class TSortedMap;
    template<typename ElementType,bool bInAllowDuplicateKeys = false> struct DefaultKeyFuncs;
    template<typename InElementType, typename KeyFuncs = DefaultKeyFuncs<InElementType>, typename Allocator = FDefaultSetAllocator> class TSet;
    template<typename InElementType, typename InSizeType = int32> class TStridedView;
    template<typename T, typename SizeType = int32> using TConstStridedView = TStridedView<const T, SizeType>;
    /// @endcond
    

    FString的分配器TSizedDefaultAllocator == TSizedHeapAllocator

    • 使用的为类型为32的堆分配器 由FMemory管理控制内存
    class FString
    {
    public:
        using AllocatorType = TSizedDefaultAllocator<32>;
    
    template <int IndexSize> class TSizedDefaultAllocator : public TSizedHeapAllocator<IndexSize>
     { public: typedef TSizedHeapAllocator<IndexSize> Typedef; };
    
    

    相关文章

      网友评论

          本文标题:12 UE5 内存分配器Allocator介绍

          本文链接:https://www.haomeiwen.com/subject/lqnwadtx.html