Ah, thanks for the clarification!
You can dump info on the references that keep an object alive via the “obj refs name=/Engine/Transient.AssetData” console command.
This produces an output like this:
LogReferenceChain: Display: InitialGather memory usage: 3.26 LogReferenceChain: (refcounted<1>) (root) ContentBrowserAssetDataSource /Engine/Transient.AssetData is not currently reachable but it does have some of EInternalObjectFlags_RootFlags set. LogReferenceChain: Display: Post-search memory usage: 1.44
The important part are the “(refcounted<1>) (root)” parts before the object.
There are no regular references to the object (i.e. via UProperties), but it is using refcounting and is part of the root set.
After running your example code the “(refcounted<1>)” part disappears, so at this point the StrongObjectPtr is correctly reset and the refcount is 0.
However, the object is also still rooted, which will keep it alive indefinitely, regardless of any references existing or not.
I haven’t been able to track down where the object is being rooted, but you can clear that flag like this and it should properly remove the object on the next GC:
UObject* obj = StaticFindObjectFast(nullptr, GetTransientPackage(), TEXT("AssetData")); obj->RemoveFromRoot();
I’ve done a short test and this seems to remove the regular assets from the content browser. I don’t think this source was designed to be runtime removable, so there’s still a chance for problems down the road.
Best,
Sebastian