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