destroy - object destruction method
obj.destroy()
Objects about to be destroyed due to garbage collection.
None
None
When a dynamically-created object is about to be destroyed due to garbage collection, if it has a destroy method, that method will be called before the object is completedly destroyed. An object that is pending final destruction is termed a zombie. All references to dynamic values in the object are replaced with nil, and the object is made read-only. However, if a new reference to the zombie object is created during execution of the destroy method, then the object is resurrected (but in the read-only state with its dynamic value references still changed to nil).
Although it is allowable to directly call an object's destroy method, it is not generally encouraged. It is a fatal error to attempt to call oadl::gc during destroy method processing.
class cls {
public proc destroy() {
"cls.destroy()\n";
}
}
// Create a dynamici object
a = new cls()
// Remove all references to that object
a = nil
// Call garbage collection - the destroy method
// will be called
oadl::gc()
cls.destroy()
// Demonstrate zombie processing
var z
var resurrect = true
class foo {
public var a, b;
public proc create(x) {
a = @x; b = x;
"foo.create - returning ", self, '\n';
}
public proc destroy() {
"", self, ".destroy() {\n";
" self.readonly() = ", self.readonly(), '\n';
" oadl::deleted(self) = ", oadl::deleted(self), '\n';
" dynamic copy ", a, " vs static ref ", b, '\n';
"}\n";
if (resurrect) z = self;
}
}
a = new foo("foo")
foo.create - returning #OBJ(1)
a = nil
oadl::gc()
#OBJ(1).destroy() {
self.readonly() = true
oadl::deleted(self) = true
dynamic copy nil vs static ref foo
}
// Set z.b to a dynamic copy of the string - it will get deleted
// next time around
z.b = @z.b
"Examining resurrected zombie ", z, '\n'
Examining resurrected zombie #OBJ(1)
"z.b = ", z.b, '\n'
z.b = foo
"oadl::deleted(z) = ", oadl::deleted(z), '\n'
oadl::deleted(z) = false
resurrect = false
z = nil
oadl::gc()
#OBJ(1).destroy() {
self.readonly() = true
oadl::deleted(self) = true
dynamic copy nil vs static ref nil
}
// Demonstrate illegal recursive GC
class badGC {
public proc destroy() { oadl::gc(); }
}
a = new badGC()
a = nil
oadl::gc()
Recursive GC