LoadGameAsyncのバックグラウンド処理で生成されたUObjectが解放されない

お世話になっております。

以下の状況でWindowsの環境でNewObjectされたUSaveGameが解放されない問題について、対処方法についての相談となります。

ISaveGameSystem::LoadGameAsync内から呼ばれる

bool FMySaveGameSystem::LoadGame(bool bAttemptToUseUI, const TCHAR* Name, const int32 UserIndex, TArray<uint8>& Data)

での処理内での以下関数で生成したUSaveGameがGCで解放されずゲーム終了時まで残り続けるという現象があり

bool IsValid() const { USaveGame* data = UGameplayStatics::LoadGameFromMemory(Data); return data != nullptr; }

そこで、下記フォーラムでの状況を参考にGarbageCollectionKeepFlags のクリアをしたところ、GCで解放されるようになりました。

[Content removed]

bool IsValid() const { USaveGame* data = UGameplayStatics::LoadGameFromMemory(Data); data->ClearInternalFlags(EInternalObjectFlags::GarbageCollectionKeepFlags); return data != nullptr; }

ただ、使用しているUEはUE5.3に以下フォーラムにあるタスクをBusyWaitの対象外にするパッチ

[Content removed]

とCL:30626322

を当てたものになり、そのタスク内でのことなので、パッチになにか不足していることによる副作用なのか?とも懸念しています。

この現象を解決するために、良い方法があればご教授いただけないでしょうか。

以上となります。

よろしくお願いいたします。

GameThread以外のスレッドで作成されたオブジェクトにEInternalObjectFlags::Asyncが付与されてGCから保護されるのは仕様です。(UObjectBase::AddObjectを参照)

このように作成されたオブジェクトに対しては作成者が適切なタイミングで(安全のためには適切に参照が接続されたプロパティに保存されたのちにGameThread上で)Asyncフラグを落とす必要があります。

標準のAsyncのセーブデータロード関数であるUGameplayStatics::AsyncLoadGameFromSlotでは、オブジェクト作成を含むLoadGameFromMemory関数はゲームスレッド上で呼ばれるようになっておりますのでこのような問題は起きません。

CL30626322につきましてはこの動作とは無関係だと考えられます。

ご教授ありがとうございました。

仕様とのことなので、自身でフラグを落とすようにしたいと思います。