Unload Async Loaded Asset from Memory in Game Instance

I am finding and loading character assets (Casting to a Base Character Class, with 2 variables, a string and a map of Soft Object Reference->Struct_MapStringString) so tat I can get the MetaData variable (string-Stringmap), set MetaData for Asset, then set a variable in a SavGame Object so that i can save soft object references and MetaData I need on assets without loading the entire asset in the future.

Problem is, once I am done with the object, how do I Manually call garbage collect, or manually unload the asset/object from memory when I am done using it?

Async must be done in Game Instance, as i was not able to do it in an Event in my SubSystem Class
Async cannot be done in a function, and from what I fuond in a post (I now cannot find) someone had a ā€œhackā€ to set the variable from the Async Load Asset Node to None.

How do I manually call Garbage Collection or make sure these assets are unloaded?



Any help would be great - Blueprint Only - or if someone comes across that other post and can link

The system should unload automatically, as long as the object you loaded is not being referenced. I don’t think there is a ā€˜call garbage collect’ in BP.

However, when I’m looking at your code, I might warn you about this

image

I got stung by this recently. The crucial thing to know, is that the calls to ā€˜initialize character asset’ do not necessarily come in the same order as the loop. You have to forget about that pin between ā€˜Completed’ and the next node. It’s much more like a totally independent event, or call back.

1 Like

I came across somewhere (That post I can’t find now) where someone had stated that the Result of the Async Load node was staying in memory, and forever due to Game Instance, and they found a hack to get it to Garbage Collect, it was somehow setting the result to none!?

I am aware that node will be called whenever the asset is done loading, its a callback function to a subsystem, and does not matter what order the function is called in relation to the original array

1 Like

I know the example you’re talking about, if the loaded object is saved to a reference, then setting the reference to null will release the object to GC.

Basically, if there was a runtime reference viewer, you need to make sure the object isn’t referenced.

Very difficult to check though :slight_smile:

obraz

2 Likes

Ha! - and yes, I think I used it a couple of weeks ago :joy:

At least I said ā€˜think’…


The returned Asset Object is Fed to this Event
The reference is converted to soft reference before being sent to the SaveGame Object

I am trying to use Soft References everywhere, and hopefully my subsystems will have the only variables with Hard References

I was thinking in that post, they did not set it to a variable, they just called the Async, then had dragged off he result to null it somehow, oh wait, maybe they did set a variable and thn null th variable. I really wish I could find that post again.

image
There is this, but for AssetData Struct, is there something like this for an Object? Was hoping to call it after GC to see if it is still loaded?

Take into account that hard casting to a class loads it into memory. Not sure if
obraz

is the soft reference you are trying to load later but this will probably throw a spanner in the works.
If you are casting to it elsewhere then that for sure will block the unloading from memory.

You should be passing in a soft object or class reference and using that to do the function.

So, I changed to this…


and this…

I suppose I should track how many are loaded and run GC after X amount instead calling GC after each one at end of that event?

What kind of map is that, it looks like soft ->hard?

What kind of map is that, it looks like soft ->hard?

Also, I saw this…

You referring to this?

Yeah, I came across that as well. A little confusing to me, but I think I understand what they are saying, but not entirely positive lol.

From what I gather, the class will be loaded into memory, which is ok, if it does not load datainto memory from child classes.

The actual object though, I am hoping will not be kept in memory. I add to the MetaData variable on te object, then get that MetaData from object to set the variable on the SaveGame object, this way the SaveGame will have any MetaData the Object may contain that was set at DevTime.

I did it this way because its an event an no local variables, and if I set the Meta on SaveGame Variable, I will have to find it, get the map, and the new meta then add to map again.Seemed cleaner the way i did it.?

I mean this map

Soft object references become marked as unloaded once the corresponding actor is destroyed

Once the GC is triggered either automatically with time or enforced with the garbage collection node the references will be marked as unloaded.

AsyncLoadTest.zip (105.2 KB)

edit:
If you want to work with the classes themselves then you would need to use the FStreamableManager to load / unload assets

1 Like

Ah…no, that is a Soft Object Reference → Struct
The Struct is a single Map Variable of String->Struct_StringMap
The String Map is a Map Variable of String-String (if its hard to understand what im saying)

This is for actors though, via blueprint, you can create an object, but unlike an actor, I do not know of a way to destroy an object, and as far as I understand, that object will stay in memory even through Garbage Collection if a hard reference exists anywhree
Which tells me I need to be very thorough using soft references, since I have no way of manually destroying, I can only make sure nothing is referencing it

In my video you can see that the scene memory goes to nearly zero after calling the CG. As long as you keep all references as soft the memory for the actors will be freed. Only class definitions stay in memory.

second this, you cant ASync load on a loop if you need to reference the object OnCompleted, i mean you can do it but you WILL get bugs.

the second problem is if the Event gets called again which calls the loop again will give even more bugs.

You can MarkAsGarbage() in C++ but probably not useful here.
CollectGarbage wont do anything if the Object isnt already Marked.

also nodes on the event graph (like AsyncLoadAsset) hold their output object forever, so the object will still be referenced.

Also i wouldnt even worry about soft references to base assets like CharacterBase because (i assume) your character will always exist so it’ll always be in memory anyway.

Exactly what I’m trying to say :slight_smile:

You can load in a loop ( or quickly ), but you need to be able to figure out which callback you’re on later :rofl:

1 Like

I’m wondering if the same async load node is used repeatedly, I assume only the most recent reference is kept?