On our project we use a large number of level instances which themselves are shared between a large number of levels. I investigated a performance issue today which will occur when you delete a level instance from a level. Render thread time went from 14.6ms to 60.58ms, RHI time went from 8.27ms to 48.39ms.
It took a while to uncover what was happening, but it turns out that when you delete an actor it does a reference search for soft object pointers for things which could be referencing that actor (see callstack). In doing this, it will load all other UWorlds that reference the LI. If those UWorlds themselves have ALevelInstance, it would then in turn load those UWorlds as well. This leads to an explosion of UWorlds which allocate FScenes, each of which are iterated for rendering in FEngineLoop::Tick();
I tried forcing GC to try to cleanup the old UWorlds, however that does not reduce the allocated FScene objects, so I’m not actually sure how we can help our content team fix this problem.
UnrealEditor-Renderer.dll!FRendererModule::AllocateScene(UWorld * World, bool bInRequiresHitProxies, bool bCreateFXSystem, ERHIFeatureLevel::Type InFeatureLevel) Line 6754 C++
UnrealEditor-Engine.dll!UWorld::InitWorld(const FWorldInitializationValues IVS) Line 2338 C++
UnrealEditor-UnrealEd.dll!UEditorEngine::InitializeNewlyCreatedInactiveWorld(UWorld * World) Line 6084 C++
> UnrealEditor-UnrealEd.dll!UEditorEngine::OnAssetLoaded(UObject * Asset) Line 5997 C++
[External Code]
[Inline Frame] UnrealEditor-CoreUObject.dll!TMulticastDelegateBase<FDefaultDelegateUserPolicy>::Broadcast(UObject *) Line 258 C++
[Inline Frame] UnrealEditor-CoreUObject.dll!TMulticastDelegate<void __cdecl(UObject *),FDefaultDelegateUserPolicy>::Broadcast(UObject *) Line 1080 C++
UnrealEditor-CoreUObject.dll!FAsyncLoadingThread2::ConditionalProcessEditorCallbacks() Line 10868 C++
UnrealEditor-CoreUObject.dll!FAsyncLoadingThread2::FlushLoading(TArrayView<int const ,int> RequestIDs) Line 11376 C++
UnrealEditor-CoreUObject.dll!FlushAsyncLoading(TArrayView<int const ,int> RequestIds) Line 362 C++
UnrealEditor-CoreUObject.dll!FlushAsyncLoading(int RequestId) Line 331 C++
UnrealEditor-CoreUObject.dll!LoadPackageInternal(UPackage * InOuter, const FPackagePath & PackagePath, unsigned int LoadFlags, FLinkerLoad * ImportLinker, FArchive * InReaderOverride, const FLinkerInstancingContext * InstancingContext, const FPackagePath * DiffPackagePath) Line 1771 C++
UnrealEditor-CoreUObject.dll!LoadPackage(UPackage * InOuter, const FPackagePath & PackagePath, unsigned int LoadFlags, FArchive * InReaderOverride, const FLinkerInstancingContext * InstancingContext, const FPackagePath * DiffPackagePath) Line 2135 C++
UnrealEditor-CoreUObject.dll!LoadPackage(UPackage * InOuter, const wchar_t * InLongPackageNameOrFilename, unsigned int LoadFlags, FArchive * InReaderOverride, const FLinkerInstancingContext * InstancingContext) Line 2111 C++
UnrealEditor-AssetTools.dll!FAssetRenameManager::GatherReferencingObjects(TArray<FAssetRenameDataWithReferencers,TSizedDefaultAllocator<32>> & AssetsToRename, TMap<FSoftObjectPath,TArray<UObject *,TSizedDefaultAllocator<32>>,FDefaultSetAllocator,TDefaultMapHashableKeyFuncs<FSoftObjectPath,TArray<UObject *,TSizedDefaultAllocator<32>>,0>> & OutSoftReferencingObjects) Line 1118 C++
UnrealEditor-AssetTools.dll!FAssetRenameManager::FindSoftReferencesToObjects(const TArray<FSoftObjectPath,TSizedDefaultAllocator<32>> & TargetObjects, TMap<FSoftObjectPath,TArray<UObject *,TSizedDefaultAllocator<32>>,FDefaultSetAllocator,TDefaultMapHashableKeyFuncs<FSoftObjectPath,TArray<UObject *,TSizedDefaultAllocator<32>>,0>> & ReferencingObjects) Line 213 C++
UnrealEditor-UnrealEd.dll!UUnrealEdEngine::DeleteActors(const TArray<AActor *,TSizedDefaultAllocator<32>> & InActorsToDelete, UWorld * InWorld, UTypedElementSelectionSet * InSelectionSet, const bool bVerifyDeletionCanHappen, const bool bWarnAboutReferences, const bool bWarnAboutSoftReferences) Line 923 C++
2026-04-23_14h51_50.png(228 KB)