Hi,
I noticed in our project that our used slate memory was going up when switching between levels. After some careful analysis of memory traces, I noticed widget components consistently being mentioned. Some debugging later, and I discovered why: the widget component doesn’t clean up its virtual window properly under several circumstances.
For some reason, RemoveWidgetFromScreen invalidates the SlateWindow shared pointer, without actually unregistering the virtual window inside it. Because of this, whenever the component is destroyed, the code that is supposed to clean up the window can’t, because the pointer is gone.
void UWidgetComponent::RemoveWidgetFromScreen()
{
#if !UE_SERVER
if (!IsRunningDedicatedServer())
{
if(SlateWindow != nullptr)
{
ResetWorldUserFocusOnWidget();
if(GetWidgetSpace() == EWidgetSpace::World)
{
SlateWindow->SetContent(SNullWidget::NullWidget);
}
SlateWindow.Reset();
}
Several other places call RemoveWidgetFromScreen and so they may leak the virtual window, for example:
- Setting the widget manually, both with a slate widget and a UMG Widget
- Setting the widget’s owning local player
- Whenever the widget is added to the screen? This one is a bit weird, but the UpdateWidgetOnScreen function has a call to it.
Does a fix or workaround for this exist? While the leak isn’t that big, it does accumulate over time, and makes profiling memory for other aspects of the project more difficult.
Thanks in advance.
[Attachment Removed]