HI, is this a bug?
UWorld::OnPostGC(), which removes stale UMaterialParameterCollectionInstance (MPCI) entries from a world’s
ParameterCollectionInstances array, is registered ONLY inside UWorld::InitWorld(). However, streaming sublevel
worlds never call InitWorld() (acknowledged in an engine comment at World.cpp line ~6206). As a result, any MPCI
entries pointing to a GC’d UMaterialParameterCollection asset will remain in those worlds’ arrays permanently,
causing a growing memory leak over the lifetime of a session.
Engine Version
--------------
UE 5.x (reproduced on our internal fork based on 5.7.1)
Root Cause
----------
1. Registration is gated behind InitWorld
-----------------------------------------
// World.cpp -- UWorld::InitWorld()
FCoreUObjectDelegates::GetPostGarbageCollect().AddUObject(this, &UWorld::OnPostGC);
This is the ONLY place OnPostGC is subscribed. Streaming sublevel worlds are loaded via
PostLoad -> SetupParameterCollectionInstances(), and explicitly skip InitWorld:
// World.cpp -- UWorld::CleanupWorld()
// "It is currently valid to call CleanupWorld on the UWorld of
// streaming sublevels, and they never call InitWorld."
2. MPCI entries are injected into all worlds including sublevel worlds
--------------------------------------------------------------------
When a UMaterialParameterCollection asset is loaded, PostLoad calls
SetupWorldParameterCollectionInstances(), which iterates EVERY live UWorld:
// ParameterCollection.cpp
void UMaterialParameterCollection::SetupWorldParameterCollectionInstances()
{
for (TObjectIterator\<UWorld\> It(...); It; \+\+It)
{
UWorld\* CurrentWorld \= \*It;
// ...
CurrentWorld\-\>AddParameterCollectionInstance(this, true); // injected into sublevel worlds too
}
}
3. OnPostGC cleanup never fires for sublevel worlds
--------------------------------------------------
// World.cpp -- UWorld::OnPostGC()
void UWorld::OnPostGC()
{
for (int32 InstanceIndex \= ParameterCollectionInstances.Num()\-1; InstanceIndex \>\= 0; InstanceIndex\-\-)
{
if (!ParameterCollectionInstances\[InstanceIndex]\-\>IsCollectionValid())
{
ParameterCollectionInstances.RemoveAt(InstanceIndex); // never reached for sublevel worlds
}
}
}
Because the callback was never registered, stale MPCI entries accumulate in every sublevel world’s
ParameterCollectionInstances array indefinitely.
can you comfire is it a bug, and can you give me a fix
[Attachment Removed]