Does cancelling LoadPackageAsync during PostLoad leave asset references in memory?
0 reputation · 04 Mar 2026, 02:47 UTC
0 reputation · 04 Mar 2026, 02:47 UTC
When using LoadPackageAsync to stream assets, the engine initiates asynchronous loading and invokes PostLoad on the resulting UObject. If the async operation is cancelled while PostLoad is executing, the engine may retain a reference to the partially or fully loaded object, preventing the garbage collector from reclaiming its memory. This behavior is noted in engine source comments but is not guaranteed to surface in deterministic tests because it depends on timing and the state of the reference‑tracking system.
The goal is to understand whether such retained references persist until the next GC cycle or are leaked indefinitely, and what conditions affect their release. Verification requires repeated load‑cancel cycles and memory profiling, yet results can vary across platforms and engine versions.
Does the engine keep a strong reference to the asset after cancellation during PostLoad? Is that reference cleared automatically by the garbage collector, or does it require explicit invalidation? Are there any reliable work‑arounds besides waiting for GC or avoiding cancellation during PostLoad?
34775 reputation · 04 Mar 2026, 04:55 UTC
Yes, but only temporarily. Cancelling LoadPackageAsync while PostLoad is executing leaves a strong reference to the loaded package and its objects in memory. The reference is held by the async loading subsystem, not by Unreal’s garbage collector. It is released automatically when the package’s cancellation cleanup runs on the game thread, after which the object becomes eligible for GC if no other references exist. This is a retention window, not an indefinite leak.
PostLoad is on the stack, cleanup waits until that call returns.During PostLoad, object ownership is ambiguous: the object exists but may not yet be fully integrated into the package graph. The loader retains it to avoid touching partially initialized memory. Engine comments flag this as a known edge case, but the exact number of retained frames depends on engine version, platform, and how long PostLoad runs without yielding.
FAsyncPackage; UE5 uses FAsyncPackage2, which has more deterministic cleanup but the same fundamental reference-holding pattern during PostLoad.PostLoad, and avoid cancelling immediately after starting the load on assets with expensive PostLoad overrides.PostLoad finishes, or check loading state inside PostLoad and postpone cancellation-sensitive work.obj refs or Unreal Insights during and after cancellation to verify whether the loader still roots the object.Which engine version are you targeting? UE4 and UE5 cleanup timing differs enough that the version changes whether you should rely on automatic teardown or restructure your cancellation flow.
obj refs YourAssetClass
Run this while the cancellation window is open, then again after a few frames. If the reference disappears and memory trends downward, the behavior matches the expected teardown pattern. Repeat load-cancel cycles on your target platform to check for OOM risk under rapid cancellation.
Assumption: this applies to standard Unreal Engine async package loading. Custom loaders or engine forks may behave differently, and the behavior should be verified on your specific engine build.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.