Page 1 of 1
Mutable Vec3D
Posted: 24 May 2025, 14:33
by SmartfoxEnjoyer
If we could have a mutable Vec3D and handle multithreading ourselves that would be great. Now I can have 10.000s of allocations of new Vec3Ds every second, thats a lot of garbage...
Re: Mutable Vec3D
Posted: 24 May 2025, 15:37
by Lapo
Not necessarily, I don't think 10K lite objects such as Vec3D can have much of an impact.
The JVM is very efficient at dealing with short lived objects.
handle multithreading ourselves
I am not sure what you mean by that...
Cheers
Re: Mutable Vec3D
Posted: 12 Nov 2025, 21:21
by mete2221
SmartfoxEnjoyer wrote:If we could have a mutable Vec3D and handle multithreading ourselves that would be great. Now I can have 10.000s of allocations of new Vec3Ds every second, thats a lot of garbage...
Isn't
Vec3D Pooling enough to prevent this?
Re: Mutable Vec3D
Posted: 23 Nov 2025, 23:36
by SmartfoxEnjoyer
mete2221 wrote: 12 Nov 2025, 21:21
SmartfoxEnjoyer wrote:If we could have a mutable Vec3D and handle multithreading ourselves that would be great. Now I can have 10.000s of allocations of new Vec3Ds every second, thats a lot of garbage...
Isn't
Vec3D Pooling enough to prevent this?
How do you change the x,y,z values of a pooled Vec3D? You cant so pooling it is useless...
Re: Mutable Vec3D
Posted: 25 Nov 2025, 08:10
by Lapo
It isn't worth caching/pooling objects this small. An object pool has performance costs, including synchronization, so you end up trading a GC pass with another thing that is likely more expensive.
Short lived small objects such as Vec3D have very small impact on the GC, especially with modern JVMs.
Check this out:
This is VisualVM attached to a small Java Test app that generates ~30K Vec3D objects/sec.
You can barely see any activity in the GC graph on the left. The max value I've spotted is 1.1%. (running on Java11, single thread, 5 years old laptop)
Cheers
Re: Mutable Vec3D
Posted: 26 Nov 2025, 20:44
by mete2221
Lapo wrote: 25 Nov 2025, 08:10
It isn't worth caching/pooling objects this small. An object pool has performance costs, including synchronization, so you end up trading a GC pass with another thing that is likely more expensive.
Short lived small objects such as Vec3D have very small impact on the GC, especially with modern JVMs.
Check this out:
GCTest.jpg
This is VisualVM attached to a small Java Test app that generates ~30K Vec3D objects/sec.
You can barely see any activity in the GC graph on the left. The max value I've spotted is 1.1%. (running on Java11, single thread, 5 years old laptop)
Cheers
Considering that a game like Project Zomboid is being made, with thousands of NPCs constantly moving around, wouldn't this create a very significant distribution?
After all, even if you were to simulate 24 frames, the Vec3D allocation of thousands of zombies would be insane.
Re: Mutable Vec3D
Posted: 27 Nov 2025, 08:15
by Lapo
It seems you're keeping a very narrow focus on one tiny detail. In a scenario where you run a 24fps simulation with 1000s of NPCs updating X times per second, the biggest performance pressure will be on the MMO system, keeping track of every object and every entity that requires an update, and relative thousands of outgoing packets.
I can guarantee (from experience) that if you run a profiler in the JVM and sort the memory usage by instance count, Vec3D will not show up in the first page of the allocations view. Maybe not even in the 2nd page.
But that's not the point:
1) if you make Vec3D mutable and store it in some kind of cache, you're just trading the cost of a GC pass (highly optimized native code in the JVM) with that of cache itself (continuous lookups, insertions/removals and relative synchronization). I'd bet the latter is more expensive than the former.
2) you're also ignoring that the JVM can do all sorts of optimizations on immutable objects, for example via escape analysis. This means that not all allocations are done on the heap (so no GC).
https://medium.com/@AlexanderObregon/th ... 2c17860b8c
3) more importantly making Vec3D mutable is just not possible, it would break the internal MMO system.
When you pass these objects around they are stored as state in the system, and if you go around and reuse them, you will erroneously overwrite the internal state of the system, breaking it.
Immutability is definitely the correct way to go in a multi-threaded system/API to ensure correctness, performance and mental sanity for both maintainers and developers.
Cheers
Re: Mutable Vec3D
Posted: 22 Dec 2025, 17:31
by SmartfoxEnjoyer
I have looked at this more deeply aswell, and indeed mmo room update interval is very important.
MMORoom positions for user and objects(like bullets even) in my opinion should be used only as a snapshot store to facilitate the clients AoI functioning correctly.
Dont use MMORoom position every frame if your server runs at 24 frames. Set the position of your users and objects only say every 6th or even every 12th frame. Then if you need to do frame-by-frame collision resolution you need to store a position variable inside each user and/or object and update that every frame and use that for collision and other simulation business. Thats how you can have 1000s of zombies moving around in real time every frame without the mmoroom proximityManager becoming a bottleneck.
But I havent profiled Vec3D usage, but in the case i described above, which im doing now in my project aswell, i only allocate a Vec3D every 12th frame for every user/obj that is actually in motion.So Lapo is correct, its the best you can do is use an immutable class for a multi-thread system like this and have devs practice correct usage of the MMORoom API.
EDIT: Also I want to add im using Java 21 for about 2 months now with SFS2X without any issues, considering JVM 21 is even more optimized and the GC is also upgraded this Vec3D allocation really is a nothingburger. (and i just saw Lapos benchmark which also seems to point at this because he was using JVM 11)