circle-loader
by
45/ 0

3、パージのプロセス

パージと参照マーカーは個別に実行できます。通常、パージはフレームごとにインクリメントして実行されます。

IncrementalPurgeGarbage(bool bUseTimeLimit、float TimeLimit)を呼び出して、2つのパラメーターを受け入れ、ガベージパージを行います。

  • bUseTimeLimit:パージの時間制限があるかどうか
  • TimeLimit:メソッドの1回の実行の時間制限

この2つのパラメーターを使用してインクリメンタルクリーニングまたはフルクリーニングを選択的に実行できます。

最初に、UnhashUnreachableObjectsメソッドが呼び出され、RF_BeginDestroyedが設定されていないすべての到達不能なUObjectに対してBeginDestroyメソッドが呼び出され、UObjectが破棄されることを通知して、UObjectが非同期パージ操作を実行できるようにします。カスタム操作を実行するために、BeginDestroyメソッドを上書き処理できます。

その後、GCロックを取得できます。

パージするオブジェクトをトラバースし、それらのオブジェクトのFinishDestroyメソッドを呼び出します。ただし、オブジェクトがBeginDestroyを終了していない可能性があります。レンダリングスレッドが使い果たされるのを待機しているグラフィックアセットなど、非同期操作があるため、これらのオブジェクトはすぐにFinishDestroyを呼び出すことはできません。代わりに、まずGGCObjectsPendingDestruction配列に配置した後に処理します。トラバーサルプロセス中に、経過時間がチェックされます。制限時間に達すると、途中で停止し、現在の進行状況を記録してから、パージプロセスを終了します。

パージするすべてのオブジェクトをトラバースした場合、つまり、それらに対してFinishDestroyメソッドを呼び出すことを試みた場合は、GGCObjectsPendingDestruction配列を再度トラバースし、FinishDestroyの実行を再試行します。このGGCObjectsPendingDestructionのトラバーサルが完了したら、TimeLimitを使用するかどうかを確認する必要があります。 TimeLimitを使用すると、次のロジックが直接実行され、GGCObjectsPendingDestruction内のオブジェクトが次回処理されます。使用しない場合は、この場所でブロックされ、それらのUObjectがBeginDestroyの実行を終了することを強制的に待機し、主にレンダリングスレッドを待機します。GGCObjectsPendingDestruction内のすべてのオブジェクトがFinishDestroyを実行した後、次のパージ操作が実行されます。

次は、実際のパージプロセスです。これは主に、パージされるオブジェクトをトラバースし、UObjectのデストラクタを実行し、メモリスペースを解放します。この手順では、リリースがTimeLimitを超えていることも確認し、超過分は次のフレームで引き続きパージされます。


 

3.1 UObjectへのポインタがどのようにNULLに更新されるか

これは、拡張された質問です。UobjectのDestroy()関数の呼び出しを表示して、UObjectが次のガベージコレクションでリサイクルされるようにすることができますが、UObjectのUPropertyポインター、またはコンテナー内のポインターはどうなりますか。ダングリングポインタということが引き起こされるか?答えはノーです。UE4を使用した後、UPropertyポインターが有効かどうかを判断するには、それが空かどうかを判断するだけでよいことがわかります。これにより、C++の開発に非常に便利です。オブジェクトが破棄されると、UE4はオブジェクトを指すUPropertyポインターを自動的にNullに更新します。UPropertyではないポインターは更新されず、ダングリングポインターの問題が発生します。 UE4の公式ドキュメントに詳細な説明(Automatic Updating of References)があります。

3.2ポインターの自動更新の実現原理

到達可能性分析フェーズでは、各オブジェクトのtokenstreamを解析して、現在のオブジェクトによって参照されている他のオブジェクトを見つけます。他のオブジェクトがPendingKillとしてマークされている場合、そのオブジェクトへのポインターはNULLに設定されます。したがって、ポインタの更新プロセスでは、最初に破棄するオブジェクトへのすべてのポインタをNULLに設定し、次にオブジェクトを破棄して、ダングリングポインタの問題が発生しないようにします。


 

UWA公式サイト:https://jp.uwa4d.com

UWA公式ブログ:https://blog.jp.uwa4d.com

UWA公式QAコミュニティ(中国語注意)https://answer.uwa4d.com