Module: ObjectSpace
- Defined in:
- gc.c
Overview
The ObjectSpace
module contains a number of routines that interact with the garbage collection facility and allow you to traverse all living objects with an iterator.
ObjectSpace
also provides support for object finalizers, procs that will be called when a specific object is about to be destroyed by garbage collection.
include ObjectSpace
a = "A"
b = "B"
c = "C"
define_finalizer(a, proc {|id| puts "Finalizer one on #{id}" })
define_finalizer(a, proc {|id| puts "Finalizer two on #{id}" })
define_finalizer(b, proc {|id| puts "Finalizer three on #{id}" })
produces:
Finalizer three on 537763470
Finalizer one on 537763480
Finalizer two on 537763480
Class Method Summary collapse
-
._id2ref(object_id) ⇒ Object
Converts an object id to a reference to the object.
-
.add_finalizer ⇒ Object
deprecated.
-
.call_finalizer ⇒ Object
deprecated.
-
.define_finalizer(obj, aProc = proc()) ⇒ Object
Adds aProc as a finalizer, to be called after obj was destroyed.
-
.each_object([) {|obj| ... } ⇒ Fixnum
Calls the block once for each living, nonimmediate object in this Ruby process.
-
.finalizers ⇒ Object
deprecated.
-
.garbage_collect ⇒ Object
Initiates garbage collection, unless manually disabled.
-
.remove_finalizer ⇒ Object
deprecated.
-
.undefine_finalizer(obj) ⇒ Object
Removes all finalizers for obj.
Class Method Details
._id2ref(object_id) ⇒ Object
Converts an object id to a reference to the object. May not be called on an object id passed as a parameter to a finalizer.
s = "I am a string" #=> "I am a string"
r = ObjectSpace._id2ref(s.object_id) #=> "I am a string"
r == s #=> true
|
# File 'gc.c'
/*
* call-seq:
* ObjectSpace._id2ref(object_id) -> an_object
*
* Converts an object id to a reference to the object. May not be
* called on an object id passed as a parameter to a finalizer.
*
* s = "I am a string" #=> "I am a string"
* r = ObjectSpace._id2ref(s.object_id) #=> "I am a string"
* r == s #=> true
*
*/
static VALUE
id2ref(obj, objid)
VALUE obj, objid;
{
unsigned long ptr, p0;
int type;
rb_secure(4);
p0 = ptr = NUM2ULONG(objid);
if (ptr == Qtrue) return Qtrue;
if (ptr == Qfalse) return Qfalse;
if (ptr == Qnil) return Qnil;
if (FIXNUM_P(ptr)) return (VALUE)ptr;
ptr = objid ^ FIXNUM_FLAG; /* unset FIXNUM_FLAG */
if ((ptr % sizeof(RVALUE)) == (4 << 2)) {
ID symid = ptr / sizeof(RVALUE);
if (rb_id2name(symid) == 0)
rb_raise(rb_eRangeError, "%p is not symbol id value", p0);
return ID2SYM(symid);
}
if (!is_pointer_to_heap((void *)ptr)||
(type = BUILTIN_TYPE(ptr)) > T_SYMBOL || type == T_ICLASS) {
rb_raise(rb_eRangeError, "0x%lx is not id value", p0);
}
if (BUILTIN_TYPE(ptr) == 0 || RBASIC(ptr)->klass == 0) {
rb_raise(rb_eRangeError, "0x%lx is recycled object", p0);
}
return (VALUE)ptr;
}
|
.add_finalizer ⇒ Object
deprecated
|
# File 'gc.c'
/* deprecated
*/
static VALUE
add_final(os, block)
VALUE os, block;
{
rb_warn("ObjectSpace::add_finalizer is deprecated; use define_finalizer");
if (!rb_respond_to(block, rb_intern("call"))) {
rb_raise(rb_eArgError, "wrong type argument %s (should be callable)",
rb_obj_classname(block));
}
rb_ary_push(finalizers, block);
return block;
}
|
.call_finalizer ⇒ Object
deprecated
|
# File 'gc.c'
/*
* deprecated
*/
static VALUE
call_final(os, obj)
VALUE os, obj;
{
rb_warn("ObjectSpace::call_finalizer is deprecated; use define_finalizer");
need_call_final = 1;
FL_SET(obj, FL_FINALIZE);
return obj;
}
|
.define_finalizer(obj, aProc = proc()) ⇒ Object
Adds aProc as a finalizer, to be called after obj was destroyed.
|
# File 'gc.c'
/*
* call-seq:
* ObjectSpace.define_finalizer(obj, aProc=proc())
*
* Adds <i>aProc</i> as a finalizer, to be called after <i>obj</i>
* was destroyed.
*
*/
static VALUE
define_final(argc, argv, os)
int argc;
VALUE *argv;
VALUE os;
{
VALUE obj, block, table;
rb_scan_args(argc, argv, "11", &obj, &block);
if (argc == 1) {
block = rb_block_proc();
}
else if (!rb_respond_to(block, rb_intern("call"))) {
rb_raise(rb_eArgError, "wrong type argument %s (should be callable)",
rb_obj_classname(block));
}
need_call_final = 1;
if (!FL_ABLE(obj)) {
rb_raise(rb_eArgError, "cannot define finalizer for %s",
rb_obj_classname(obj));
}
RBASIC(obj)->flags |= FL_FINALIZE;
block = rb_ary_new3(2, INT2FIX(ruby_safe_level), block);
OBJ_FREEZE(block);
if (!finalizer_table) {
finalizer_table = st_init_numtable();
}
if (st_lookup(finalizer_table, obj, &table)) {
rb_ary_push(table, block);
}
else {
table = rb_ary_new3(1, block);
RBASIC(table)->klass = 0;
st_add_direct(finalizer_table, obj, table);
}
return block;
}
|
.each_object([) {|obj| ... } ⇒ Fixnum
Calls the block once for each living, nonimmediate object in this Ruby process. If module is specified, calls the block for only those classes or modules that match (or are a subclass of) module. Returns the number of objects found. Immediate objects (Fixnum
s, Symbol
s true
, false
, and nil
) are never returned. In the example below, each_object
returns both the numbers we defined and several constants defined in the Math
module.
a = 102.7
b = 95 # Won't be returned
c = 12345678987654321
count = ObjectSpace.each_object(Numeric) {|x| p x }
puts "Total count: #{count}"
produces:
12345678987654321
102.7
2.71828182845905
3.14159265358979
2.22044604925031e-16
1.7976931348623157e+308
2.2250738585072e-308
Total count: 7
|
# File 'gc.c'
/*
* call-seq:
* ObjectSpace.each_object([module]) {|obj| ... } => fixnum
*
* Calls the block once for each living, nonimmediate object in this
* Ruby process. If <i>module</i> is specified, calls the block
* for only those classes or modules that match (or are a subclass of)
* <i>module</i>. Returns the number of objects found. Immediate
* objects (<code>Fixnum</code>s, <code>Symbol</code>s
* <code>true</code>, <code>false</code>, and <code>nil</code>) are
* never returned. In the example below, <code>each_object</code>
* returns both the numbers we defined and several constants defined in
* the <code>Math</code> module.
*
* a = 102.7
* b = 95 # Won't be returned
* c = 12345678987654321
* count = ObjectSpace.each_object(Numeric) {|x| p x }
* puts "Total count: #{count}"
*
* <em>produces:</em>
*
* 12345678987654321
* 102.7
* 2.71828182845905
* 3.14159265358979
* 2.22044604925031e-16
* 1.7976931348623157e+308
* 2.2250738585072e-308
* Total count: 7
*
*/
static VALUE
os_each_obj(argc, argv, os)
int argc;
VALUE *argv;
VALUE os;
{
VALUE of;
rb_secure(4);
if (argc == 0) {
of = 0;
}
else {
rb_scan_args(argc, argv, "01", &of);
}
RETURN_ENUMERATOR(os, 1, &of);
return os_obj_of(of);
}
|
.finalizers ⇒ Object
deprecated
|
# File 'gc.c'
/*
* deprecated
*/
static VALUE
finals()
{
rb_warn("ObjectSpace::finalizers is deprecated");
return finalizers;
}
|
.start ⇒ nil .garbage_collect ⇒ nil .garbage_collect ⇒ nil
Initiates garbage collection, unless manually disabled.
|
# File 'gc.c'
/*
* call-seq:
* GC.start => nil
* gc.garbage_collect => nil
* ObjectSpace.garbage_collect => nil
*
* Initiates garbage collection, unless manually disabled.
*
*/
VALUE
rb_gc_start()
{
rb_gc();
return Qnil;
}
|
.remove_finalizer ⇒ Object
deprecated
|
# File 'gc.c'
/*
* deprecated
*/
static VALUE
rm_final(os, block)
VALUE os, block;
{
rb_warn("ObjectSpace::remove_finalizer is deprecated; use undefine_finalizer");
rb_ary_delete(finalizers, block);
return block;
}
|
.undefine_finalizer(obj) ⇒ Object
Removes all finalizers for obj.
|
# File 'gc.c'
/*
* call-seq:
* ObjectSpace.undefine_finalizer(obj)
*
* Removes all finalizers for <i>obj</i>.
*
*/
static VALUE
undefine_final(os, obj)
VALUE os, obj;
{
if (finalizer_table) {
st_delete(finalizer_table, (st_data_t*)&obj, 0);
}
return obj;
}
|