I try debug this problem by memory insights. Set Time A after step 1, and Time B after step 6.And I found the BulkData causes the problem.The payload of BulkData of LandscapeNaniteComponent’s UStaticMesh is a SharedBuffer, and finally in step 6 its RefCount reamins one, which from the FBulkDataRegistryImpl::Registry. When FBulkDataRegistryImpl::OnExitMemory is called, the BulkData of LandscapeNaniteComponent’s UStaticMesh just sets bInMemory to false (Existing->BulkData.IsMemoryOnlyPayload() = false), and do not release the RAM.It is not memory-only-payload.If I force execute “Existing→BulkData.Reset()“, it likes fixed and no memory leaks.But I do not know its consequence, it may cause other problems?
I’m rookie in unreal bulk data management.So I’m confused why.When I batch build nanite by code like the repro steps for a 16K landscape, this will cause OOM when RAM go to more than 160G.Please Help~
UE 5.6.1(Both code build and launch can repro this problem)
Repro steps:
1.Create a World-Partition-enabled Level, Create a 2K size landscape(Section Size = 255, World Partition Region Size = 4, others default) and enable landscape nanite.Now all LandscapeStreamingProxies are unloaded.
2.Pin parts of LandscapeStreamingProxies(like pin 4 proxies) on Outliner panel to load them, select them and build nanite from button on details panel.
3.Save these pinned LandscapeStreamingProxies.
4.Unpin these LandscapeStreamingProxies to unload them.
5.Repeat step 2,3,4 to build all LandscapeStreamingProxies.
6.Switch to another empty level, execute “Obj GC”.Memory leak about 4~5G(Total RAM go from 6.4G to 11.5G.
I have been able to reproduce the leak with the information provided. I couldn’t not find the reason the BuilkData is not destroyed when the owning component is. I do not recommend to reset the BulkData member as it’s state is linked to other members of that class and you could end up loosing data. It might not be a big problem as that data is generated from the landscape sculpt and could always be regenerated.
[Image Removed]Thank you for your help. I tried debugging the problem for some days, but I still couldn’t resolve it by myself ever I found where the memory leaked. The relative codes are too complex to me. It will help me a lot if the problem is resolved. I met a problem when viewing the issue web like the snapshot. How can I view the issue web successfully? Thank you again for your help.
There are two sources of BulkData leaks. Source A is from the newly registered BulkData after LandscapeNaniteComponent builds Nanite. Source B is from the old StaticMesh before executing “Component->SetStaticMesh(InStaticMesh);” in function ULandscapeNaniteComponent::InitializeForLandscapeAsync.
My fix for A:
Add a FinishDestroy implementation to LandscapeNaniteComponent, and call FEditorBulkData::UnloadData() for the BulkData registered in the Registry. Perhaps it will reload from DDC by “FEditorBulkData::GetPayload()” when needed next time?
My fix for B:
Since “Component->SetStaticMesh(InStaticMesh);” will be executed, the old mesh will no longer be needed. Call “SrcModel.StaticMeshDescriptionBulkData->Empty();” before setting the new one.
It seems to work, but I’m not sure what else might go wrong, and this is only a temporary solution. I’d like to track this issue and wait for the proper fix.