ID:1108928
 
(See the best response by Stephen001.)
Code:
/obj/test/proc/Kill()
del(src) // Delete all references to this object

/obj/test/Del()
loc = null // Null the only reference
..() // Will it still check even if I nulled out the only reference?


Problem description:

In the deconstructor I null out the only reference to the object. When Kill() is called, it will call the deconstructor via del(src) and then proceed to check for references.

When ..() is executed, will it efficiently check that there ARE references to null before looping for references and nulling them out? I was hoping by doing this I could optimize existing code to be friendly with the Garbage Collector.

Or will I have to create a separate proc which will make my object be garbage collected.
Best response
If the only reference is the location on the map and you are sure of this, is there any particular reason you don't just do this?

/obj/test/proc/Kill()
src.loc = null


This means that the reference count hits zero as you state, but the VM doesn't need to act upon it yet.

The issue with del() is predominantly the need to reclaim memory, clean up appearance structures, inform the clients of the object's deletion, check references as you said etc. These are all things the VM will do anyway if the reference count hits zero, it's just del() forces the VM to do it right now, for one object.

Leaving the reference count as zero and not firing off del() yourself allows the VM to perform the operation at it's convenience, and if there are many such objects, in bulk. Meaning a more even CPU use spread because of deferred reclamation, a quicker reference check (per object), quicker resource writing to caches (per object) and better use of the network bandwidth to clients.

Your optimisation is pretty much not to call del() in this scenario or define your own destructor, and just let the VM take care of it.
Ah, thanks for the reply. I'll take note of this.
In response to Stephen001
Stephen001 wrote:
If the only reference is the location on the map and you are sure of this, is there any particular reason you don't just do this?

> /obj/test/proc/Kill()
> src.loc = null
>

This means that the reference count hits zero as you state, but the VM doesn't need to act upon it yet.

The issue with del() is predominantly the need to reclaim memory, clean up appearance structures, inform the clients of the object's deletion, check references as you said etc. These are all things the VM will do anyway if the reference count hits zero, it's just del() forces the VM to do it right now, for one object.

Leaving the reference count as zero and not firing off del() yourself allows the VM to perform the operation at it's convenience, and if there are many such objects, in bulk. Meaning a more even CPU use spread because of deferred reclamation, a quicker reference check (per object), quicker resource writing to caches (per object) and better use of the network bandwidth to clients.

Your optimisation is pretty much not to call del() in this scenario or define your own destructor, and just let the VM take care of it.

Just to clarify what constitutes actually being "Dead".

1. location set to null
2. nothing else is referencing the object
-images, overlays, and other "static" versions of the object don't count

??
Well, it's basically just "nothing else is referencing the object".

When you have a location set on an object, it will live in the contents list of the turf at that location, hence the reference.

Images, overlays etc. are related to an icon resource, not the object, and the icon doesn't reference the object, the object references the icon. Most image/overlay operations are clone operations, producing a distinct new in-memory appearance object, which is reference counted as it's own thing.

There is one notable exception to the "Nothing must reference the object" rule that I know of. world.contents may (and indeed has to) reference it, as it does to all atoms. This is basically a weak reference, and doesn't contribute to the reference count.
This seriously just changed my server cpu from 50 to 15 during "intensive" operations.
It really will, yeah. Forced delete tends to be quite an expensive operation in most managed languages, and BYOND is certainly no exception. Glad to hear it's helped!