虚幻4 OBJECT内存分配和初始化
2016-09-28 02:15
423 查看
首先,蓝图调用实在CPP调用之后执行。
模块加载时候回调用所有的UClass的CreateDefaultObject函数,产生默认的OBJECT,以后拷贝默认的就行了
在任何一个Actor构造函数里面打断点,然后play
UnrealEngine\Engine\Source\Runtime\CoreUObject\Private\UObject\UObjectGlobals.cpp
Result = StaticAllocateObject(InClass, InOuter, InName, InFlags, InternalSetFlags, bCanRecycleSubobjects, &bRecycledSubobject);
上面这一行分配内存
(*InClass->ClassConstructor)( FObjectInitializer(Result, InTemplate, bCopyTransientsFromClassDefaults, true, InInstanceGraph) );
上面这一行调用构造函数,我猜应该是先把上面构造那个默认的给拷贝过来,然后再调用下面的初始化函数。
参数类型为FObjectInitializer的构造函数是在自动生成的generate.h文件中声明的,类似于这样,我的这个类名是AGame1Character
DEFINE_DEFAULT_OBJECT_INITIALIZER_CONSTRUCTOR_CALL这个宏是这样
#define DEFINE_DEFAULT_OBJECT_INITIALIZER_CONSTRUCTOR_CALL(TClass) \
static void __DefaultConstructor(const FObjectInitializer& X) { new((EInternal*)X.GetObj())TClass(X);
enum EInternal {EC_InternalUseOnlyConstructor};
placement new 直接在返回的object指针位置调用了构造函数。然后就调到我们写的构造函数,(上面那个还有个无参数版本,类似于 TClass())
引擎一开始先开辟一个数组,存放所有的活着的UOBJECT。其实就是个Object的指针和这个object的flag。
maloc其实就是单纯的开辟内存,目前没有发现内存池在哪里。在我的PC上是英特尔的TBB算法(TBB(intel threading building blocks)内存分配算法)。
Engine_Updating\Engine\Source\Runtime\CoreUObject\Private\UObject\UObjectArray.cpp
void FUObjectArray::AllocateObjectPool(int32 InMaxUObjects, int32 InMaxObjectsNotConsideredByGC)
{
check(IsInGameThread());
MaxObjectsNotConsideredByGC = InMaxObjectsNotConsideredByGC;
// GObjFirstGCIndex is the index at which the garbage collector will start for the mark phase.
// If disregard for GC is enabled this will be set to an invalid value so that later we
// know if disregard for GC pool has already been closed (at least once)
ObjFirstGCIndex = DisregardForGCEnabled() ? -1 : 0;
// Pre-size array.
check(ObjObjects.Num() == 0);
UE_CLOG(InMaxUObjects <= 0, LogUObjectArray, Fatal, TEXT("Max UObject count is invalid. It must be a number that is greater than 0."));
ObjObjects.PreAllocate(InMaxUObjects);
if (MaxObjectsNotConsideredByGC > 0)
{
ObjObjects.AddRange(MaxObjectsNotConsideredByGC);
}
}
模块加载时候回调用所有的UClass的CreateDefaultObject函数,产生默认的OBJECT,以后拷贝默认的就行了
在任何一个Actor构造函数里面打断点,然后play
UnrealEngine\Engine\Source\Runtime\CoreUObject\Private\UObject\UObjectGlobals.cpp
UObject* StaticConstructObject_Internal ( UClass* InClass, UObject* InOuter /*=GetTransientPackage()*/, FName InName /*=NAME_None*/, EObjectFlags InFlags /*=0*/, EInternalObjectFlags InternalSetFlags /*=0*/, UObject* InTemplate /*=NULL*/, bool bCopyTransientsFromClassDefaults /*=false*/, FObjectInstancingGraph* InInstanceGraph /*=NULL*/ ) { SCOPE_CYCLE_COUNTER(STAT_ConstructObject); UObject* Result = NULL; #if WITH_EDITORONLY_DATA UE_CLOG(GIsSavingPackage && InOuter != GetTransientPackage(), LogUObjectGlobals, Fatal, TEXT("Illegal call to StaticConstructObject() while serializing object data! (Object will not be saved!)")); #endif checkf(!InTemplate || InTemplate->IsA(InClass) || (InFlags & RF_ClassDefaultObject), TEXT("StaticConstructObject %s is not an instance of class %s and it is not a CDO."), *GetFullNameSafe(InTemplate), *GetFullNameSafe(InClass)); // template must be an instance of the class we are creating, except CDOs // Subobjects are always created in the constructor, no need to re-create them unless their archetype != CDO or they're blueprint generated. // If the existing subobject is to be re-used it can't have BeginDestroy called on it so we need to pass this information to StaticAllocateObject. const bool bIsNativeClass = InClass->HasAnyClassFlags(CLASS_Native | CLASS_Intrinsic); const bool bIsNativeFromCDO = bIsNativeClass && ( !InTemplate || (InName != NAME_None && InTemplate == UObject::GetArchetypeFromRequiredInfo(InClass, InOuter, InName, InFlags)) ); #if WITH_HOT_RELOAD // Do not recycle subobjects when performing hot-reload as they may contain old property values. const bool bCanRecycleSubobjects = bIsNativeFromCDO && !GIsHotReload; #else const bool bCanRecycleSubobjects = bIsNativeFromCDO; #endif bool bRecycledSubobject = false; Result = StaticAllocateObject(InClass, InOuter, InName, InFlags, InternalSetFlags, bCanRecycleSubobjects, &bRecycledSubobject); check(Result != NULL); // Don't call the constructor on recycled subobjects, they haven't been destroyed. if (!bRecycledSubobject) { FScopeCycleCounterUObject ConstructorScope(InClass, GET_STATID(STAT_ConstructObject)); (*InClass->ClassConstructor)( FObjectInitializer(Result, InTemplate, bCopyTransientsFromClassDefaults, true, InInstanceGraph) ); } if( GIsEditor && GUndo && (InFlags & RF_Transactional) && !(InFlags & RF_NeedLoad) && !InClass->IsChildOf(UField::StaticClass()) ) { // Set RF_PendingKill and update the undo buffer so an undo operation will set RF_PendingKill on the newly constructed object. Result->MarkPendingKill(); SaveToTransactionBuffer(Result, false); Result->ClearPendingKill(); } return Result; }
Result = StaticAllocateObject(InClass, InOuter, InName, InFlags, InternalSetFlags, bCanRecycleSubobjects, &bRecycledSubobject);
上面这一行分配内存
(*InClass->ClassConstructor)( FObjectInitializer(Result, InTemplate, bCopyTransientsFromClassDefaults, true, InInstanceGraph) );
上面这一行调用构造函数,我猜应该是先把上面构造那个默认的给拷贝过来,然后再调用下面的初始化函数。
参数类型为FObjectInitializer的构造函数是在自动生成的generate.h文件中声明的,类似于这样,我的这个类名是AGame1Character
#define Game1_Source_Game1_Game1Character_h_9_STANDARD_CONSTRUCTORS \ /** Standard constructor, called after all reflected properties have been initialized */ \ NO_API AGame1Character(const FObjectInitializer& ObjectInitializer); \ DEFINE_DEFAULT_OBJECT_INITIALIZER_CONSTRUCTOR_CALL(AGame1Character) \ DECLARE_VTABLE_PTR_HELPER_CTOR(NO_API, AGame1Character); \ DEFINE_VTABLE_PTR_HELPER_CTOR_CALLER(AGame1Character); \
DEFINE_DEFAULT_OBJECT_INITIALIZER_CONSTRUCTOR_CALL这个宏是这样
#define DEFINE_DEFAULT_OBJECT_INITIALIZER_CONSTRUCTOR_CALL(TClass) \
static void __DefaultConstructor(const FObjectInitializer& X) { new((EInternal*)X.GetObj())TClass(X);
enum EInternal {EC_InternalUseOnlyConstructor};
placement new 直接在返回的object指针位置调用了构造函数。然后就调到我们写的构造函数,(上面那个还有个无参数版本,类似于 TClass())
引擎一开始先开辟一个数组,存放所有的活着的UOBJECT。其实就是个Object的指针和这个object的flag。
maloc其实就是单纯的开辟内存,目前没有发现内存池在哪里。在我的PC上是英特尔的TBB算法(TBB(intel threading building blocks)内存分配算法)。
Engine_Updating\Engine\Source\Runtime\CoreUObject\Private\UObject\UObjectArray.cpp
void FUObjectArray::AllocateObjectPool(int32 InMaxUObjects, int32 InMaxObjectsNotConsideredByGC)
{
check(IsInGameThread());
MaxObjectsNotConsideredByGC = InMaxObjectsNotConsideredByGC;
// GObjFirstGCIndex is the index at which the garbage collector will start for the mark phase.
// If disregard for GC is enabled this will be set to an invalid value so that later we
// know if disregard for GC pool has already been closed (at least once)
ObjFirstGCIndex = DisregardForGCEnabled() ? -1 : 0;
// Pre-size array.
check(ObjObjects.Num() == 0);
UE_CLOG(InMaxUObjects <= 0, LogUObjectArray, Fatal, TEXT("Max UObject count is invalid. It must be a number that is greater than 0."));
ObjObjects.PreAllocate(InMaxUObjects);
if (MaxObjectsNotConsideredByGC > 0)
{
ObjObjects.AddRange(MaxObjectsNotConsideredByGC);
}
}
相关文章推荐
- Java基础-对象的内存分配与初始化
- 内存分配成功,但并未初始化
- Objective-C 学习笔记 - part 3 - 为对象分配内存并初始化
- C/C++ struct初始化/复制/内存分配技巧
- Java的初始化机制、垃圾回收机制和内存分配机制
- java数组的初始化与内存分配
- 为什么给一个字符串分配内存再初始化后,其大小一直为8?
- 关于Java变量的声明、内存分配及初始化详解
- 分配内存和初始化
- Object C 内存分配大小
- 关于,函数调用是传值调用,初始化函数中重新分配内存,导致形参的值和实参的值不一致 问题分析
- C语言中的初始化及内存分配
- 类中指针成员的内存分配和初始化
- C语言calloc()函数:分配内存空间并初始化
- 全局变量,静态全局变量,静态局部变量,类静态成员内存分配与初始化问题
- C/C++ struct初始化/复制/内存分配技巧
- Java数组概述、定义格式说明、初始化、内存分配及常见操作
- .net类的初始化机制,顺序,内存分配,
- C++用new动态分配数组内存后用()进行初始化
- C/C++ struct初始化/复制/内存分配技巧