Xcode Instruments中的Allocations和Leaks

使用Xcode Instruments中的Allocations和Leaks的工具,可以帮忙开发者定位潜在的内存问题,发现不合预期的分配和泄漏。

Allocations:Analyzes the memory life-cycle of process's allocated blocks, can record reference counting events.

                  可以跟踪App的每一处在Heap、Anonymous VM、All VM Regions上的内存分配

Leaks:Examines a process's heap for leaked memory; use with Allocations instrument to give memory address histories.

             抓取内存泄漏

环境参数配置

Build Configuration需选择非Editor的选项,如:Debug、DebugGame、Development、Test或Shipping。

Executalbe如果不修改的话,需要将ipa包后缀改成zip并解压,然后将Payload整个目录拷贝到MyTest1/Binaries/IOS中。也可以选择一个ipa包,指向包中的MyTest1.app。

定义环境变量:UE4_FORCE_MALLOC_ANSI(强制使用ansi malloc)

Profile中勾选“Use the Run action's arguments and environment variables

(1)执行  菜单:Product -- Perform Action -- Profile Without Building

(2)拉起instruments之后,选择手机和上面的app进程,选择Allocations工具,点击“Choose”按钮来进入profiler界面

(3)点击右上角的+按钮,添加Leaks工具,点击左上角的红圈按钮,来启动进行profiler

使用Allocations跟踪内存分配

注:开了环境变量UE4_FORCE_MALLOC_ANSI后,Allocations -- Call Trees中会多一个AnsiMalloc的分类,这个分类中为UE4内存分配后没有释放的内存

注1:IOGPUResourceCreate为显卡上分配的图形资源 

注2:Command + A全选,然后右键菜单“Copy Selected Frames”,将完整堆栈复制出来(含源代码文件名和代码行) -- 代码行可能会有偏差

  66 libsystem_malloc.dylib    3.54 MB     realloc
  65 UAGame    3.54 MB     AnsiRealloc(void*, unsigned long, unsigned int) [inlined] /Users/admin/1030Version/UnrealEngine/Engine/Source/Runtime/Core/Private/HAL/MallocAnsi.cpp:68
  64 UAGame    3.54 MB     FMallocAnsi::TryRealloc(void*, unsigned long, unsigned int) [inlined] /Users/admin/1030Version/UnrealEngine/Engine/Source/Runtime/Core/Private/HAL/MallocAnsi.cpp:195
  63 UAGame    3.54 MB     FMallocAnsi::Realloc(void*, unsigned long, unsigned int) /Users/admin/1030Version/UnrealEngine/Engine/Source/Runtime/Core/Private/HAL/MallocAnsi.cpp:202
  62 UAGame    3.54 MB     FMemory::Realloc(void*, unsigned long, unsigned int) /Users/admin/1030Version/UnrealEngine/Engine/Source/Runtime/Core/Public/HAL/FMemory.inl:0
  61 UAGame    2.58 MB     TSizedHeapAllocator<32>::ForAnyElementType::ResizeAllocation(int, int, unsigned long) [inlined] /Users/admin/1030Version/UnrealEngine/Engine/Source/Runtime/Core/Public/Containers/ContainerAllocationPolicies.h:480
  60 UAGame    2.58 MB     TArray<TSparseArrayElementOrFreeListLink<TAlignedBytes<24, 8u> >, TSizedDefaultAllocator<32> >::ResizeGrow(int) /Users/admin/1030Version/UnrealEngine/Engine/Source/Runtime/Core/Public/Containers/Array.h:2559
  59 UAGame    2.34 MB     TArray<TSparseArrayElementOrFreeListLink<TAlignedBytes<24, 8u> >, TSizedDefaultAllocator<32> >::AddUninitialized(int) [inlined] /Users/admin/1030Version/UnrealEngine/Engine/Source/Runtime/Core/Public/Containers/Array.h:1290
  58 UAGame    2.34 MB     TSparseArray<TSetElement<TTuple<UObjectBase*, int> >, TSparseArrayAllocator<TSizedDefaultAllocator<32>, FDefaultBitArrayAllocator> >::AddUninitialized() /Users/admin/1030Version/UnrealEngine/Engine/Source/Runtime/Core/Public/Containers/SparseArray.h:129
  57 UAGame    2.34 MB     FSetElementId TSet<TTuple<UObjectBase*, int>, TDefaultMapHashableKeyFuncs<UObjectBase*, int, false>, FDefaultSetAllocator>::Emplace<TPairInitializer<UObjectBase*&&, int const&> >(TPairInitializer<UObjectBase*&&, int const&>&&, bool*) [inlined] /Users/admin/1030Version/UnrealEngine/Engine/Source/Runtime/Core/Public/Containers/Set.h:665
  56 UAGame    2.34 MB     int& TMapBase<UObjectBase*, int, FDefaultSetAllocator, TDefaultMapHashableKeyFuncs<UObjectBase*, int, false> >::Emplace<UObjectBase*, int const&>(UObjectBase*&&, int const&) [inlined] /Users/admin/1030Version/UnrealEngine/Engine/Source/Runtime/Core/Public/Containers/Map.h:404
  55 UAGame    2.34 MB     TMapBase<UObjectBase*, int, FDefaultSetAllocator, TDefaultMapHashableKeyFuncs<UObjectBase*, int, false> >::Add(UObjectBase*&&, int const&) [inlined] /Users/admin/1030Version/UnrealEngine/Engine/Source/Runtime/Core/Public/Containers/Map.h:364
  54 UAGame    2.34 MB     FLuaContext::NotifyUObjectCreated(UObjectBase const*, int) /Users/admin/1030Version/R6Game/Plugins/Tencent/UnLua/Source/UnLua/Private/LuaContext.cpp:986
  53 UAGame    2.34 MB     FUObjectArray::AllocateUObjectIndex(UObjectBase*, bool) /Users/admin/1030Version/UnrealEngine/Engine/Source/Runtime/CoreUObject/Private/UObject/UObjectArray.cpp:251
  52 UAGame    2.34 MB     UObjectBase::AddObject(FName, EInternalObjectFlags) /Users/admin/1030Version/UnrealEngine/Engine/Source/Runtime/CoreUObject/Private/UObject/UObjectBase.cpp:188
  51 UAGame    2.34 MB     UObjectBase::UObjectBase(UClass*, EObjectFlags, EInternalObjectFlags, UObject*, FName) [inlined] /Users/admin/1030Version/UnrealEngine/Engine/Source/Runtime/CoreUObject/Private/UObject/UObjectBase.cpp:116
  50 UAGame    2.34 MB     UObjectBase::UObjectBase(UClass*, EObjectFlags, EInternalObjectFlags, UObject*, FName) /Users/admin/1030Version/UnrealEngine/Engine/Source/Runtime/CoreUObject/Private/UObject/UObjectBase.cpp:113
  49 UAGame    2.34 MB     StaticAllocateObject(UClass const*, UObject*, FName, EObjectFlags, EInternalObjectFlags, bool, bool*, UPackage*) /Users/admin/1030Version/UnrealEngine/Engine/Source/Runtime/CoreUObject/Private/UObject/UObjectGlobals.cpp:2520
  48 UAGame    2.34 MB     StaticConstructObject_Internal(FStaticConstructObjectParameters const&) /Users/admin/1030Version/UnrealEngine/Engine/Source/Runtime/CoreUObject/Private/UObject/UObjectGlobals.cpp:3210
  47 UAGame    2.34 MB     StaticDuplicateObjectEx(FObjectDuplicationParameters&) /Users/admin/1030Version/UnrealEngine/Engine/Source/Runtime/CoreUObject/Private/UObject/UObjectGlobals.cpp:2025
  46 UAGame    2.34 MB     AActor::CreateComponentFromTemplate(UActorComponent*, FName) /Users/admin/1030Version/UnrealEngine/Engine/Source/Runtime/Engine/Private/ActorConstruction.cpp:1287
  45 UAGame    2.34 MB     USCS_Node::ExecuteNodeOnActor(AActor*, USceneComponent*, FTransform const*, FRotationConversionCache const*, bool) /Users/admin/1030Version/UnrealEngine/Engine/Source/Runtime/Engine/Private/SCS_Node.cpp:97
  44 UAGame    2.34 MB     USimpleConstructionScript::ExecuteScriptOnActor(AActor*, TInlineComponentArray<USceneComponent*, 24u> const&, FTransform const&, FRotationConversionCache const*, bool) /Users/admin/1030Version/UnrealEngine/Engine/Source/Runtime/Engine/Private/SimpleConstructionScript.cpp:689
  43 UAGame    2.34 MB     AActor::ExecuteConstruction(FTransform const&, FRotationConversionCache const*, FComponentInstanceDataCache const*, bool) /Users/admin/1030Version/UnrealEngine/Engine/Source/Runtime/Engine/Private/ActorConstruction.cpp:874
  42 UAGame    2.34 MB     AActor::FinishSpawning(FTransform const&, bool, FComponentInstanceDataCache const*) /Users/admin/1030Version/UnrealEngine/Engine/Source/Runtime/Engine/Private/Actor.cpp:3504
  41 UAGame    2.34 MB     AActor::PostSpawnInitialize(FTransform const&, AActor*, APawn*, bool, bool, bool) /Users/admin/1030Version/UnrealEngine/Engine/Source/Runtime/Engine/Private/Actor.cpp:3424
  40 UAGame    2.34 MB     UWorld::SpawnActor(UClass*, FTransform const*, FActorSpawnParameters const&) /Users/admin/1030Version/UnrealEngine/Engine/Source/Runtime/Engine/Private/LevelActor.cpp:428
  39 UAGame    2.34 MB     UWorld::SpawnActor(UClass*, FVector const*, FRotator const*, FActorSpawnParameters const&) /Users/admin/1030Version/UnrealEngine/Engine/Source/Runtime/Engine/Private/LevelActor.cpp:303
  38 UAGame    2.34 MB     USGInventoryStatics::GetInventoryWithActorPool(UObject*, UClass*, bool, FVector const*, FRotator const*) /Users/admin/1030Version/R6Game/Plugins/SGFramework/Source/SGFramework/Private/SGGame/Inventory/SGInventoryStatics.cpp:6472
  37 UAGame    2.34 MB     USGCharacterAvatarManagerComponent::UpdateAvatars(TArray<TSubclassOf<ASGInventory>, TSizedDefaultAllocator<32> >, bool, TArray<long long, TSizedDefaultAllocator<32> >) /Users/admin/1030Version/R6Game/Plugins/SGFramework/Source/SGFramework/Private/SGGame/Components/Character/SGCharacterAvatarManagerComponent.cpp:237
  36 UAGame    2.34 MB     UUACommonStatics::UpdateAvatar(ASGCharacter*, TArray<long long, TSizedDefaultAllocator<32> >&) /Users/admin/1030Version/R6Game/Source/UACommon/Private/UACommonStatics.cpp:810
  35 UAGame    2.34 MB     UUACommonStatics::execUpdateAvatar(UObject*, FFrame&, void*) /Users/admin/1030Version/R6Game/Intermediate/Build/IOS/UAGame/Inc/UACommon/UACommonStatics.gen.cpp:517
  34 UAGame    2.34 MB     UFunction::Invoke(UObject*, FFrame&, void*) /Users/admin/1030Version/UnrealEngine/Engine/Source/Runtime/CoreUObject/Private/UObject/Class.cpp:5592
  33 UAGame    2.34 MB     FFunctionDesc::CallUE(lua_State*, int, void*) /Users/admin/1030Version/R6Game/Plugins/Tencent/UnLua/Source/UnLua/Private/ReflectionUtils/FunctionDesc.cpp:252
  32 UAGame    2.34 MB     luaD_precall /Users/admin/1030Version/R6Game/Plugins/Tencent/UnLua/Source/Others/Lua/src/ldo.c:500

在Leaks中查看泄漏的内存

注:Command + A全选,然后右键菜单“Copy Selected Frames”,将完整堆栈复制出来(含源代码文件名和代码行) -- 代码行可能会有偏差 

   0 UAGame AnsiRealloc(void*, unsigned long, unsigned int) /Users/admin/1030Version/UnrealEngine/Engine/Source/Runtime/Core/Private/HAL/MallocAnsi.cpp:72
   1 UAGame FMallocAnsi::TryRealloc(void*, unsigned long, unsigned int) /Users/admin/1030Version/UnrealEngine/Engine/Source/Runtime/Core/Private/HAL/MallocAnsi.cpp:195
   2 UAGame FMallocAnsi::Realloc(void*, unsigned long, unsigned int) /Users/admin/1030Version/UnrealEngine/Engine/Source/Runtime/Core/Private/HAL/MallocAnsi.cpp:202
   3 UAGame FMemory::Realloc(void*, unsigned long, unsigned int) /Users/admin/1030Version/UnrealEngine/Engine/Source/Runtime/Core/Public/HAL/FMemory.inl:0
   4 UAGame TSizedHeapAllocator<32>::ForAnyElementType::ResizeAllocation(int, int, unsigned long) /Users/admin/1030Version/UnrealEngine/Engine/Source/Runtime/Core/Public/Containers/ContainerAllocationPolicies.h:480
   5 UAGame TArray<char16_t, TSizedDefaultAllocator<32> >::ResizeForCopy(int, int) /Users/admin/1030Version/UnrealEngine/Engine/Source/Runtime/Core/Public/Containers/Array.h:2591
   6 UAGame void TArray<char16_t, TSizedDefaultAllocator<32> >::CopyToEmpty<char16_t, int>(char16_t const*, int, int, int) /Users/admin/1030Version/UnrealEngine/Engine/Source/Runtime/Core/Public/Containers/Array.h:2621
   7 UAGame TArray<char16_t, TSizedDefaultAllocator<32> >::TArray(TArray<char16_t, TSizedDefaultAllocator<32> > const&) /Users/admin/1030Version/UnrealEngine/Engine/Source/Runtime/Core/Public/Containers/Array.h:359
   8 UAGame TArray<char16_t, TSizedDefaultAllocator<32> >::TArray(TArray<char16_t, TSizedDefaultAllocator<32> > const&) /Users/admin/1030Version/UnrealEngine/Engine/Source/Runtime/Core/Public/Containers/Array.h:358
   9 UAGame FString::FString(FString const&) /Users/admin/1030Version/UnrealEngine/Engine/Source/Runtime/Core/Public/Containers/UnrealString.h:83
  10 UAGame FString::FString(FString const&) /Users/admin/1030Version/UnrealEngine/Engine/Source/Runtime/Core/Public/Containers/UnrealString.h:83
  11 UAGame int TArray<FString, TSizedDefaultAllocator<32> >::Emplace<FString const&>(FString const&) /Users/admin/1030Version/UnrealEngine/Engine/Source/Runtime/Core/Public/Containers/Array.h:1929
  12 UAGame TArray<FString, TSizedDefaultAllocator<32> >::Add(FString const&) /Users/admin/1030Version/UnrealEngine/Engine/Source/Runtime/Core/Public/Containers/Array.h:2002
  13 UAGame void FConfigSection::MultiFind<TSizedDefaultAllocator<32> >(FName, TArray<FString, TSizedDefaultAllocator<32> >&, bool) const /Users/admin/1030Version/UnrealEngine/Engine/Source/Runtime/Core/Public/Misc/ConfigCacheIni.h:240
  14 UAGame FConfigFile::GetArray(char16_t const*, char16_t const*, TArray<FString, TSizedDefaultAllocator<32> >&) const /Users/admin/1030Version/UnrealEngine/Engine/Source/Runtime/Core/Private/Misc/ConfigCacheIni.cpp:1976
  15 UAGame UUACommonConfigStatics::execGetServerIPConfig(UObject*, FFrame&, void*) /Users/admin/1030Version/R6Game/Intermediate/Build/IOS/UAGame/Inc/UACommon/UACommonConfigStatics.gen.cpp:578
  16 UAGame UFunction::Invoke(UObject*, FFrame&, void*) /Users/admin/1030Version/UnrealEngine/Engine/Source/Runtime/CoreUObject/Private/UObject/Class.cpp:5592
  17 UAGame FFunctionDesc::CallUE(lua_State*, int, void*) /Users/admin/1030Version/R6Game/Plugins/Tencent/UnLua/Source/UnLua/Private/ReflectionUtils/FunctionDesc.cpp:331
  18 UAGame luaD_precall /Users/admin/1030Version/R6Game/Plugins/Tencent/UnLua/Source/Others/Lua/src/ldo.c:515
  19 UAGame luaV_execute /Users/admin/1030Version/R6Game/Plugins/Tencent/UnLua/Source/Others/Lua/src/lvm.c:1134
  20 UAGame luaD_call /Users/admin/1030Version/R6Game/Plugins/Tencent/UnLua/Source/Others/Lua/src/ldo.c:621
  21 UAGame luaD_callnoyield /Users/admin/1030Version/R6Game/Plugins/Tencent/UnLua/Source/Others/Lua/src/ldo.c:631
  22 UAGame luaD_rawrunprotected /Users/admin/1030Version/R6Game/Plugins/Tencent/UnLua/Source/Others/Lua/src/ldo.c:146
  23 UAGame luaD_pcall /Users/admin/1030Version/R6Game/Plugins/Tencent/UnLua/Source/Others/Lua/src/ldo.c:851
  24 UAGame lua_pcallk /Users/admin/1030Version/R6Game/Plugins/Tencent/UnLua/Source/Others/Lua/src/lapi.c:968
  25 UAGame luaB_xpcall /Users/admin/1030Version/R6Game/Plugins/Tencent/UnLua/Source/Others/Lua/src/lbaselib.c:441
  26 UAGame luaD_precall /Users/admin/1030Version/R6Game/Plugins/Tencent/UnLua/Source/Others/Lua/src/ldo.c:515
  27 UAGame luaV_execute /Users/admin/1030Version/R6Game/Plugins/Tencent/UnLua/Source/Others/Lua/src/lvm.c:1134
  28 UAGame luaD_call /Users/admin/1030Version/R6Game/Plugins/Tencent/UnLua/Source/Others/Lua/src/ldo.c:621
  29 UAGame luaD_callnoyield /Users/admin/1030Version/R6Game/Plugins/Tencent/UnLua/Source/Others/Lua/src/ldo.c:631
  30 UAGame luaD_rawrunprotected /Users/admin/1030Version/R6Game/Plugins/Tencent/UnLua/Source/Others/Lua/src/ldo.c:146
  31 UAGame luaD_pcall /Users/admin/1030Version/R6Game/Plugins/Tencent/UnLua/Source/Others/Lua/src/ldo.c:851
  32 UAGame lua_pcallk /Users/admin/1030Version/R6Game/Plugins/Tencent/UnLua/Source/Others/Lua/src/lapi.c:968
  33 UAGame UnLua::FLuaRetValues UnLua::CallFunctionInternal<float&>(lua_State*, float&) /Users/admin/1030Version/R6Game/Plugins/Tencent/UnLua/Source/UnLua/Public/UnLua.inl:106
  34 UAGame UnLua::FLuaRetValues UnLua::Call<float&>(lua_State*, char const*, float&) /Users/admin/1030Version/R6Game/Plugins/Tencent/UnLua/Source/UnLua/Public/UnLua.inl:656
  35 UAGame UG6LuaScriptManager::Tick(float) /Users/admin/1030Version/R6Game/Plugins/Tencent/G6Framework/Source/G6Core/G6/G6LuaScriptManager.cpp:164
  36 UAGame FTickableGameObject::TickObjects(UWorld*, int, bool, float) /Users/admin/1030Version/UnrealEngine/Engine/Source/Runtime/Engine/Private/Tickable.cpp:154
  37 UAGame UGameEngine::Tick(float, bool) /Users/admin/1030Version/UnrealEngine/Engine/Source/Runtime/Engine/Private/GameEngine.cpp:1856
  38 UAGame FEngineLoop::Tick() /Users/admin/1030Version/UnrealEngine/Engine/Source/Runtime/Launch/Private/LaunchEngineLoop.cpp:4836
  39 UAGame -[IOSAppDelegate MainAppThread:] /Users/admin/1030Version/UnrealEngine/Engine/Source/Runtime/ApplicationCore/Private/IOS/IOSAppDelegate.cpp:506
  40 Foundation __NSThread__start__
  41 libsystem_pthread.dylib _pthread_start
  42 libsystem_pthread.dylib thread_start

配置可执行二进制文件和符号表文件

点击Instruments的File菜单 -- Symbols...,配置各模块的可执行二进制和dSYM符号表

点击Done,会加载一阵子,完成后,Instruments捕捉的函数地址就还原成函数名了

注:Binary和dSYM文件必须同名,否则符号会加载不成功

配置Symbols路径

注:点击菜单Instruments -- Preferences...,在面板的Symbols标签页中添加dSYM的查找路径

原文地址:https://www.cnblogs.com/kekec/p/13296385.html