ID:1160496
 
Applies to:Dream Seeker
Status: Open

Issue hasn't been assigned a status value.
Similar to CPU but profiling what is using more memory in the game?
Fully support this. Why hasn't it been thought of beforehand?
Because it was traditionally nigh on impossible to hit system memory limitations. You'd have hit the ceiling of object/turf/mob limits (at 65,535 each) much before you'd have exhausted the hosts system memory.

This is actually potentially quite a big feature, that you'd want to discuss properly and put some design into. As a for-instance, what do you envisage such a feature displaying to you, in what form, how do you wish to navigate this etc etc?

Perhaps you guys could start us off on that.
A graph of memory usage over time would be incredible. Average memory used by each proc would be pretty useful too.
Why the procs, would be my question? Procedures will clean up much of their data once they complete, so their used memory when called seems a little irrelevant for debugging memory leaks. Which is I guess, why you'd want this?
In response to Stephen001
Stephen001 wrote:
Why the procs, would be my question? Procedures will clean up much of their data once they complete, so their used memory when called seems a little irrelevant for debugging memory leaks. Which is I guess, why you'd want this?

Because i thought it would be a helpful feature.

and no i have no issues with memory leaks but yes it could be used that way i suppose.

I was just using profile to check for any hogging procedures and i wondered why not memory? so i posted.
The thing is, procedures allocating objects that use a lot of memory isn't in itself problematic, and doesn't cause memory leaks or harm program performance particularly. In quite a few cases it is expected, fairly normal.

Procedures don't particularly hog memory. They're in flight for milliseconds usually, and can release local variables when they finish, or when a local variable is set to a new object value. A procedure could allocate 20 MB of memory per call and be perfectly fine, because it releases all 20 MB back when it completes some 50 milliseconds later. So profiling that isn't really a useful metric, it doesn't really work like CPU time spent.

However, a procedure that allocates a single datum per call, and never frees it (adds to some globally held list or some such, for example), is a memory leak. It will, in due time (may be a long long time) result in a program crash, unless there's a reboot to clear that.

The issue you typically want to debug is one of pinning. Basically due to reference counting, a very small object like a datum held at the top level, referring to other objects, which in turn refer to objects etc etc, will pin a lot of memory. That entire graph cannot be freed, because our little datum is in some global list, and is never removed. That is your only real use for a memory profiler for BYOND.

So your memory profiler really needs to be able to take snapshots of the entire set of objects allocated in the world, and be able to capture the reference graph, for later analysis. That may or may not be trivial, kinda depends on internals. Once done though, you can literally go "take a snapshot now .... and now" as a programmer, and do quite a lot of useful analysis by snapshot comparison.

If you have the tools. Which is where the second aspect to the feature comes in, the time-consuming, design requiring aspect. You need to process the reference graph, and calculate things like "Okay, for this little datum, it takes up 4 KB in memory. But ... it pins, 200 MB of objects, via the reference graph.", "all objects of this type take up 400 KB total directly, and 500 MB by reference graph" etc etc.

Then you need to have the UI to display that, allow the user to compare snapshots, and try to decide what they want to look at, and whether they care about direct allocation only, or pinning, or some variety of both.

Once the user's gone through all that, they need to go back to their code, work out where it's allocated, work out where it should be freed, fix it, and re-test. Rinse and repeat.