Description

Strong object reference properties of an 'EditInline'-decorated UCLASS type embedded within a native C++ struct definition can be instanced at edit time by the user as part of a variable's default value within a streaming sublevel's Blueprint class.

These subobject instances are (by design) reallocated and replaced during the Blueprint compile-on-load process at editor load time, once the map is later reloaded back into the editor. However, since these instances are owned by a streaming sublevel, they also get marked with the 'EInternalObjectFlags::AsyncLoading' flag on load, prior to being reinstanced. After reinstancing, the old, transient objects retain the flag and thus cannot be garbage collected due to the following code in FObjectIterator:

// We don't want to return any objects that are currently being background loaded unless we're using the object iterator during async loading.
 InternalExclusionFlags |= EInternalObjectFlags::Unreachable;
 if (!IsInAsyncLoadingThread())
 \{
 InternalExclusionFlags |= EInternalObjectFlags::AsyncLoading;
 }

Since they cannot be cleaned up, any attempt to unload the current world after it's been reloaded will leak these objects, and the check code will assert.

Suggestion for now is to simply restart the editor after encountering this issue.

Steps to Reproduce
  1. Start with a new, blank C++ code project.
  2. Create the following struct/class definitions in C++ code:
    UCLASS(EditInlineNew)
    class UMyObject : public UObject
    {
    	GENERATED_BODY()
    };
    
    USTRUCT(BlueprintType)
    struct FMyNativeStruct
    {
    	GENERATED_BODY()
    
    public:
    	UPROPERTY(EditAnywhere, Instanced)
    	class UMyObject* InstancedSubObject;
    };
    
  3. Compile C++ code and launch the UE4 editor for the project.
  4. Create a new level and save ("NewMap").
  5. Choose Window->Levels, then create a new streaming sublevel ("NewMap_Sub").
  6. Open the sublevel's script Blueprint and add a new variable (NewVar_0).
  7. Change the variable's type to 'MyNativeStruct'.
  8. Compile, select the variable and look at the default value in the Details tab.
  9. Click the drop-down arrow and select "MyObject" to instance a new object.
  10. Compile and save the sublevel.
  11. Choose File->New Level and create a new, default level. Choose to save "NewMap" if prompted.
  12. Double-click the "NewMap" asset to reopen the level that was previously opened.
  13. Again, choose File->New Level and attempt to create a new, default level. A crash will result with a number of errors in the log output of the form:
    LogEditorServer: Error: Old level package /Game/NewMap not cleaned up by garbage collection while loading new map! Referenced by:
    (asyncloading) MyObject /Engine/Transient.Default__NewMap_Sub_C:MyObject_0->Outer
     REINST_NewMap_Sub_C_74 /Engine/Transient.Default__NewMap_Sub_C->Class
      BlueprintGeneratedClass /Engine/Transient.REINST_NewMap_Sub_C_74::AddReferencedObjects(): REINST_NewMap_Sub_C_74
       LevelScriptBlueprint /Game/NewMap_Sub.NewMap_Sub:PersistentLevel.NewMap_Sub->Outer
        Level /Game/NewMap_Sub.NewMap_Sub:PersistentLevel->OwningWorld
         World /Game/NewMap.NewMap->ThumbnailInfo
          WorldThumbnailInfo /Game/NewMap.NewMap:WorldThumbnailInfo_0::AddReferencedObjects()
           Package /Game/NewMap
    
Callstack

> UE4Editor-UnrealEd-Win64-Debug.dll!UEditorEngine::CheckForWorldGCLeaks(UWorld * NewWorld, UPackage * WorldPackage) Line 1992 C++
UE4Editor-UnrealEd-Win64-Debug.dll!UEditorEngine::EditorDestroyWorld(FWorldContext & Context, const FText & CleanseText, UWorld * NewWorld) Line 2115 C++
UE4Editor-UnrealEd-Win64-Debug.dll!UEditorEngine::Map_Load(const wchar_t * Str, FOutputDevice & Ar) Line 2469 C++
UE4Editor-UnrealEd-Win64-Debug.dll!UEditorEngine::HandleMapCommand(const wchar_t * Str, FOutputDevice & Ar, UWorld * InWorld) Line 6050 C++
UE4Editor-UnrealEd-Win64-Debug.dll!UEditorEngine::Exec(UWorld * InWorld, const wchar_t * Stream, FOutputDevice & Ar) Line 5586 C++
UE4Editor-UnrealEd-Win64-Debug.dll!UUnrealEdEngine::Exec(UWorld * InWorld, const wchar_t * Stream, FOutputDevice & Ar) Line 696 C++
UE4Editor-UnrealEd-Win64-Debug.dll!FEditorFileUtils::LoadMap(const FString & InFilename, bool LoadAsTemplate, const bool bShowProgress) Line 2466 C++
UE4Editor-LevelEditor-Win64-Debug.dll!FLevelEditorActionCallbacks::NewLevel() Line 226 C++
UE4Editor-LevelEditor-Win64-Debug.dll!TBaseStaticDelegateInstance<TTypeWrapper<void> __cdecl(void)>::Execute() Line 802 C++
UE4Editor-LevelEditor-Win64-Debug.dll!TBaseStaticDelegateInstance<void __cdecl(void)>::ExecuteIfSafe() Line 854 C++
UE4Editor-Slate-Win64-Debug.dll!TBaseDelegate<void>::ExecuteIfBound() Line 673 C++
UE4Editor-Slate-Win64-Debug.dll!FUICommandList::ExecuteAction(const TSharedRef<FUICommandInfo const ,0> InUICommandInfo) Line 103 C++
UE4Editor-Slate-Win64-Debug.dll!SMenuEntryBlock::OnClicked(bool bCheckBoxClicked) Line 1059 C++
UE4Editor-Slate-Win64-Debug.dll!SMenuEntryBlock::OnMenuItemButtonClicked() Line 1019 C++
UE4Editor-Slate-Win64-Debug.dll!TMemberFunctionCaller<SMenuEntryBlock,FReply (__cdecl SMenuEntryBlock::*)(void)>::operator()<>() Line 156 C++
UE4Editor-Slate-Win64-Debug.dll!TBaseSPMethodDelegateInstance<0,SMenuEntryBlock,0,FReply __cdecl(void)>::Execute() Line 293 C++
UE4Editor-Slate-Win64-Debug.dll!SButton::ExecuteOnClick() Line 385 C++
UE4Editor-Slate-Win64-Debug.dll!SButton::OnMouseButtonUp(const FGeometry & MyGeometry, const FPointerEvent & MouseEvent) Line 304 C++
UE4Editor-Slate-Win64-Debug.dll!SMenuEntryButton::OnMouseButtonUp(const FGeometry & MyGeometry, const FPointerEvent & MouseEvent) Line 384 C++
UE4Editor-Slate-Win64-Debug.dll!FSlateApplication::RoutePointerUpEvent::__l8::<lambda>(const FArrangedWidget & TargetWidget, const FPointerEvent & Event) Line 4631 C++
UE4Editor-Slate-Win64-Debug.dll!FEventRouter::Route<FReply,FEventRouter::FToLeafmostPolicy,FPointerEvent,FReply <lambda>(const FArrangedWidget &, const FPointerEvent &) >(FSlateApplication * ThisApplication, FEventRouter::FToLeafmostPolicy RoutingPolicy, FPointerEvent EventCopy, const FSlateApplication::RoutePointerUpEvent::__l8::FReply <lambda>(const FArrangedWidget &, const FPointerEvent &) & Lambda) Line 372 C++
UE4Editor-Slate-Win64-Debug.dll!FSlateApplication::RoutePointerUpEvent(const FWidgetPath & WidgetsUnderPointer, const FPointerEvent & PointerEvent) Line 4617 C++
UE4Editor-Slate-Win64-Debug.dll!FSlateApplication::ProcessMouseButtonUpEvent(const FPointerEvent & MouseEvent) Line 5140 C++
UE4Editor-Slate-Win64-Debug.dll!FSlateApplication::OnMouseUp(const EMouseButtons::Type Button, const FVector2D CursorPos) Line 5108 C++
UE4Editor-ApplicationCore-Win64-Debug.dll!FWindowsApplication::ProcessDeferredMessage(const FDeferredWindowsMessage & DeferredMessage) Line 1958 C++
UE4Editor-ApplicationCore-Win64-Debug.dll!FWindowsApplication::DeferMessage(TSharedPtr<FWindowsWindow,0> & NativeWindow, HWND__ * InHWnd, unsigned int InMessage, unsigned __int64 InWParam, __int64 InLParam, int MouseX, int MouseY, unsigned int RawInputFlags) Line 2410 C++
UE4Editor-ApplicationCore-Win64-Debug.dll!FWindowsApplication::ProcessMessage(HWND__ * hwnd, unsigned int msg, unsigned __int64 wParam, __int64 lParam) Line 959 C++
UE4Editor-ApplicationCore-Win64-Debug.dll!FWindowsApplication::AppWndProc(HWND__ * hwnd, unsigned int msg, unsigned __int64 wParam, __int64 lParam) Line 788 C++
[External Code]
UE4Editor-ApplicationCore-Win64-Debug.dll!WinPumpMessages() Line 109 C++
UE4Editor-ApplicationCore-Win64-Debug.dll!FWindowsPlatformApplicationMisc::PumpMessages(bool bFromMainLoop) Line 133 C++
UE4Editor-Win64-Debug.exe!FEngineLoop::Tick() Line 4397 C++
UE4Editor-Win64-Debug.exe!EngineTick() Line 63 C++
UE4Editor-Win64-Debug.exe!GuardedMain(const wchar_t * CmdLine, HINSTANCE__ * hInInstance, HINSTANCE__ * hPrevInstance, int nCmdShow) Line 176 C++
UE4Editor-Win64-Debug.exe!WinMain(HINSTANCE__ * hInInstance, HINSTANCE__ * hPrevInstance, char * __formal, int nCmdShow) Line 252 C++
[External Code]

Have Comments or More Details?

There's no existing public thread on this issue, so head over to Questions & Answers just mention UE-88129 in the post.

3
Login to Vote

Fixed
ComponentUE - Gameplay - Blueprint
Affects Versions4.24
Target Fix4.25
Fix Commit12010702
Main Commit12049343
Release Commit12010702
CreatedFeb 5, 2020
ResolvedMar 6, 2020
UpdatedJul 30, 2020