How to Identify which asset was loaded when profiling memory with Unreal Insights

Hi Everyone,

What is the recommended way to identify which asset(s) are being loaded for a specific allocation when analysing traces captured with Unreal Insights?

I am running traces with the “memory,metadata,assetmetadata” channels, and I can identify allocations for some assets like the one below:

[Image Removed]

But this doesn’t work for all assets. For example, some Niagara particle systems seem to allocate their own memory (GPUBufferFloat, GPUBufferInt etc.) after being loaded.

[Image Removed]

One thing I have tried is to add the “loadtime” and “assetloadtime” channels, along with the -statnamedevents flag. Traces with these additional parameters have extra tracks for asset loading, and I can eyeball memory spikes and any loads that ocurred around the same time:

[Image Removed]

And this is OK but the occaisionaly large allocation but it’s not ideal when there are multiple.

Steps to Reproduce

Hi,

In general, we track memory allocated during asset loading (see Engine\Source\Runtime\CoreUObject\Private\Serialization\AsyncLoading.cpp and AsyncLoading2.cpp) using scoped macros like:

LLM_SCOPE_DYNAMIC_STAT_OBJECTPATH(Object->GetPackage(), ELLMTagSet::Assets); LLM_SCOPE_DYNAMIC_STAT_OBJECTPATH(Object->GetClass(), ELLMTagSet::AssetClasses); UE_TRACE_METADATA_SCOPE_ASSET_FNAME(Object->GetFName(), Object->GetClass()->GetFName(), Object->GetPackage()->GetFName());These scopes are added in pairs (LLM_* + UE_TRACE_*) in order for both memory tracking systems to track similar data:

  • the UE_TRACE_* macros are used by the “memory tracing” (i.e. “-trace=memalloc,metadata,assetmetadata”; data is exposed in Insights UI by Memory Insights / Memory Investigation queries);
  • the LLM_SCOPE_* macros are used by LLM (Low Level Memory Tracker); Note that LLM data is also available to tracing / Insights using “-trace=memtag” (data is exposed in Insights UI by the new Memory Insights / Memory Tags panel, in UE 5.6).

Both “memalloc” and “memtag” channels are enabled by the “memory” channel preset, so when “-trace=memory,metadata,assetmetadata” is used, Memory Insights will show data from both memory tracking systems.

LLM mostly tracks the package names of the UObject assets, into the “Assets” tag set.

Memory tracing is trying to capture both asset (object) name and the package name.

All allocations happening during an asset loading scope are associated with the respective asset/class/package name.

But, a lot of memory is allocated outside of “asset loading” code. Even if these allocations are not really specific to an actual asset, we have used same macros to give more info to them.

For example, many allocations happening for RHI buffers and resources are also scoped with these macros. In these case, the “Asset”/“ClassName”/“Package” are not actual asset/class/package names, but RHI specific buffer names or other debug names.

Another example is Engine\Source\Runtime\Core\Private\Misc\ConfigCacheIni.cpp, where the “Asset”/“Package” is just the the config file name and the class name is specified as “ConfigFile”.

So, you need to use together info from all 3 columns (“Asset”, “ClassName”, “Package”) to figure out what are the “assets”. In the Allocs Table tree view, there are custom presets like “Asset (Package)” and “Class Name” that can be used to quickly setup groupings for these three columns.

The “loadtime”/“assetloadtime” trace channels and the “-statnamedevents” command line parameter are only used to track CPU performance of asset loading. The data tracked when these are enabled is not used in any way by the Memory Insights. Still, these can be useful just as context info (to correlate the Memory Insights timelines with CPU tracks).

  • The “-statnamedevents” command line parameter enables more detailed CPU scopes to be emitted for the “cpu” trace channel.
  • The “AssetLoadTime” trace channel is now only used for commandlets (ex. cooking) to enable tracing of object names (blueprints, functions) as cpu scopes. In this case, it also requires “cpu” channel (and “-statnamedevents”) to be enabled. The CPU scope tracing of object names (blueprints, functions) is now enabled by default when app is not running as a commandlet (still requires “cpu” trace channel and “-statnamedevents” to be enabled, but it does not require “AssetLoadTime” channel to be enabled).
  • The “LoadTime” channel will enable the Asset Loading Insights functionality (custom tracks for the async loading events and more performance data regarding asset loading available as tables).

Regards,

Ionut

Hi Ionut,

Thanks for the info. That, combined with some of the responses in another [thread [Content removed] we have been able to do most of what we wanted and get the info we needed.

I understand that there are some new feaetures coming in 5.6 as well, so I’ll keep an eye out for them and give them a try.