@rhyan.smith Thanks for the answer, here’s the post. Make sure to look at the other post as it seems like there have been assigned tickets to it that got opened and closed and I’m not sure the GC problem got solved
Here’s a repro that tries to prove class scoped weak_map(player) have the same problem. (connect a 2nd player once, make them leave, come back minutes later, crash)
unique_object := class<unique>:
MemoryIntensiveArrays : [][]float
test_array_map := class(creative_device):
var SomeWeakMap : weak_map(player, []unique_object) = map{}
# var SomeWeakMap : [unique_object]logic = map{}
HugeFloatArray : []float = for(__ := 0..1000000) {0.123456789} # Should be passed by copy as every array do
OnBegin<override>()<suspends>:void=
loop:
Player := GetPlayspace().PlayerAddedEvent().Await()
for(I := 1..250):
NewObject := unique_object:
MemoryIntensiveArrays := array:
HugeFloatArray
HugeFloatArray
HugeFloatArray
HugeFloatArray
HugeFloatArray
HugeFloatArray
HugeFloatArray
HugeFloatArray
HugeFloatArray
HugeFloatArray
if(not SomeWeakMap[Player]):
option. set SomeWeakMap[Player] = array{}
option. set SomeWeakMap[Player] += array{NewObject}
Print("Itration({I})")
Sleep(0.0)
# NewObject should be removed by garbage collector upon disconnection
This is expected behavior. weak_maps in Verse are not, as the name might suggest, containers that hold weak references to objects (something like TWeakPtr<>'s), but rather is a map structure that does not allow iteration. It only allows access directly via the key type of the weak_map.
weak_maps are most frequently used in persistence as the semantics allows a developer to access the persistence data for any player in the island, but not any data for players who are not.
In fact, Verse does not have weak pointer semantics at all. Any reference that you hold in your Verse program to a Verse object will prevent that object from being garbage collected.
In your example, the reason why it crashes is because you are creating a lot of objects that you are then holding references to in the SomeWeakMap object and never releasing them.
If you want to make sure an object gets garbage collected, the only option you have is to clear all of your references to that object.
Please let me know if you have any further questions on this.
IMO that naming design choice is really pretty weird, weak maps hold weak references in every other languages as I’m aware of.
I believe you’re mixing up weak_maps with weak_maps(player), those seem to have an overriden hidden getter on your end, they’re not the same.
Regarding weak_map(player), you said they don’t allow developers to access the persistence data for any disconnected player and they’re not holding weak references, does that mean that the disconnected player persistence data is still stored in memory and that the weak_map needs to be updated when a player disconnects? This would not be documented in the persistence docs
I would understand weak_map(session) being automatically cleaned up when the round ends, as all Verse variables actually do
Also, the Book of Verse says that “The weak_map type is a specialized supertype of map […] with weak key references”, I thought this documentation was actually written by someone at Epic, what’s up with that?