Module: ObjectSpace
- Defined in:
- gc.c,
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.
require 'objspace'
a = "A"
b = "B"
ObjectSpace.define_finalizer(a, proc {|id| puts "Finalizer one on #{id}" })
ObjectSpace.define_finalizer(b, proc {|id| puts "Finalizer two on #{id}" })
_produces:_
Finalizer two on 537763470
Finalizer one on 537763480
Defined Under Namespace
Classes: WeakMap
Class Method Summary collapse
- ._id2ref(objid) ⇒ Object
-
.count_objects([result_hash]) ⇒ Hash
Counts all objects grouped by type.
-
.define_finalizer(obj, aProc = proc()) ⇒ Object
Adds aProc as a finalizer, to be called after obj was destroyed.
-
.each_object(*args) ⇒ Object
Calls the block once for each living, nonimmediate object in this Ruby process.
-
.undefine_finalizer(obj) ⇒ Object
Removes all finalizers for obj.
Instance Method Summary collapse
- #_id2ref(objid) ⇒ Object private
-
#count_objects([result_hash]) ⇒ Hash
private
Counts all objects grouped by type.
-
#define_finalizer(obj, aProc = proc()) ⇒ Object
private
Adds aProc as a finalizer, to be called after obj was destroyed.
-
#each_object(*args) ⇒ Object
private
Calls the block once for each living, nonimmediate object in this Ruby process.
-
#undefine_finalizer(obj) ⇒ Object
private
Removes all finalizers for obj.
Class Method Details
._id2ref(objid) ⇒ Object
3679 3680 3681 3682 3683 |
# File 'gc.c', line 3679
static VALUE
os_id2ref(VALUE os, VALUE objid)
{
return id2ref(objid);
}
|
.count_objects([result_hash]) ⇒ Hash
Counts all objects grouped by type.
It returns a hash, such as:
:TOTAL=>10000,
:FREE=>3011,
:T_OBJECT=>6,
:T_CLASS=>404,
# ...
The contents of the returned hash are implementation specific. It may be changed in future.
The keys starting with :T_
means live objects. For example, :T_ARRAY
is the number of arrays. :FREE
means object slots which is not used now. :TOTAL
means sum of above.
If the optional argument result_hash
is given, it is overwritten and returned. This is intended to avoid probe effect.
h = {}
ObjectSpace.count_objects(h)
puts h
# => { :TOTAL=>10000, :T_CLASS=>158280, :T_MODULE=>20672, :T_STRING=>527249 }
This method is only expected to work on C Ruby.
4020 4021 4022 4023 4024 4025 4026 4027 4028 4029 4030 4031 4032 4033 4034 4035 4036 4037 4038 4039 4040 4041 4042 4043 4044 4045 4046 4047 4048 4049 4050 4051 4052 4053 4054 4055 4056 4057 4058 4059 4060 4061 4062 4063 4064 4065 4066 4067 4068 4069 4070 4071 4072 4073 4074 4075 4076 4077 4078 |
# File 'gc.c', line 4020
static VALUE
count_objects(int argc, VALUE *argv, VALUE os)
{
rb_objspace_t *objspace = &rb_objspace;
size_t counts[T_MASK+1];
size_t freed = 0;
size_t total = 0;
size_t i;
VALUE hash = Qnil;
if (rb_check_arity(argc, 0, 1) == 1) {
hash = argv[0];
if (!RB_TYPE_P(hash, T_HASH))
rb_raise(rb_eTypeError, "non-hash given");
}
for (i = 0; i <= T_MASK; i++) {
counts[i] = 0;
}
for (i = 0; i < heap_allocated_pages; i++) {
struct heap_page *page = heap_pages_sorted[i];
RVALUE *p, *pend;
p = page->start; pend = p + page->total_slots;
for (;p < pend; p++) {
void *poisoned = asan_poisoned_object_p((VALUE)p);
asan_unpoison_object((VALUE)p, false);
if (p->as.basic.flags) {
counts[BUILTIN_TYPE(p)]++;
}
else {
freed++;
}
if (poisoned) {
GC_ASSERT(BUILTIN_TYPE((VALUE)p) == T_NONE);
asan_poison_object((VALUE)p);
}
}
total += page->total_slots;
}
if (hash == Qnil) {
hash = rb_hash_new();
}
else if (!RHASH_EMPTY_P(hash)) {
rb_hash_stlike_foreach(hash, set_zero, hash);
}
rb_hash_aset(hash, ID2SYM(rb_intern("TOTAL")), SIZET2NUM(total));
rb_hash_aset(hash, ID2SYM(rb_intern("FREE")), SIZET2NUM(freed));
for (i = 0; i <= T_MASK; i++) {
VALUE type = type_sym(i);
if (counts[i])
rb_hash_aset(hash, type, SIZET2NUM(counts[i]));
}
return hash;
}
|
.define_finalizer(obj, aProc = proc()) ⇒ Object
Adds aProc as a finalizer, to be called after obj was destroyed. The object ID of the obj will be passed as an argument to aProc. If aProc is a lambda or method, make sure it can be called with a single argument.
3231 3232 3233 3234 3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 3245 3246 |
# File 'gc.c', line 3231
static VALUE
define_final(int argc, VALUE *argv, VALUE os)
{
VALUE obj, block;
rb_scan_args(argc, argv, "11", &obj, &block);
should_be_finalizable(obj);
if (argc == 1) {
block = rb_block_proc();
}
else {
should_be_callable(block);
}
return define_final0(obj, block);
}
|
.each_object([) {|obj| ... } ⇒ Integer .each_object([) ⇒ Object
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.
If no block is given, an enumerator is returned instead.
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
3166 3167 3168 3169 3170 3171 3172 3173 3174 |
# File 'gc.c', line 3166
static VALUE
os_each_obj(int argc, VALUE *argv, VALUE os)
{
VALUE of;
of = (!rb_check_arity(argc, 0, 1) ? 0 : argv[0]);
RETURN_ENUMERATOR(os, 1, &of);
return os_obj_of(of);
}
|
.undefine_finalizer(obj) ⇒ Object
Removes all finalizers for obj.
3184 3185 3186 3187 3188 |
# File 'gc.c', line 3184
static VALUE
undefine_final(VALUE os, VALUE obj)
{
return rb_undefine_finalizer(obj);
}
|
Instance Method Details
#_id2ref(objid) ⇒ Object (private)
3679 3680 3681 3682 3683 |
# File 'gc.c', line 3679
static VALUE
os_id2ref(VALUE os, VALUE objid)
{
return id2ref(objid);
}
|
#count_objects([result_hash]) ⇒ Hash (private)
Counts all objects grouped by type.
It returns a hash, such as:
:TOTAL=>10000,
:FREE=>3011,
:T_OBJECT=>6,
:T_CLASS=>404,
# ...
The contents of the returned hash are implementation specific. It may be changed in future.
The keys starting with :T_
means live objects. For example, :T_ARRAY
is the number of arrays. :FREE
means object slots which is not used now. :TOTAL
means sum of above.
If the optional argument result_hash
is given, it is overwritten and returned. This is intended to avoid probe effect.
h = {}
ObjectSpace.count_objects(h)
puts h
# => { :TOTAL=>10000, :T_CLASS=>158280, :T_MODULE=>20672, :T_STRING=>527249 }
This method is only expected to work on C Ruby.
4020 4021 4022 4023 4024 4025 4026 4027 4028 4029 4030 4031 4032 4033 4034 4035 4036 4037 4038 4039 4040 4041 4042 4043 4044 4045 4046 4047 4048 4049 4050 4051 4052 4053 4054 4055 4056 4057 4058 4059 4060 4061 4062 4063 4064 4065 4066 4067 4068 4069 4070 4071 4072 4073 4074 4075 4076 4077 4078 |
# File 'gc.c', line 4020
static VALUE
count_objects(int argc, VALUE *argv, VALUE os)
{
rb_objspace_t *objspace = &rb_objspace;
size_t counts[T_MASK+1];
size_t freed = 0;
size_t total = 0;
size_t i;
VALUE hash = Qnil;
if (rb_check_arity(argc, 0, 1) == 1) {
hash = argv[0];
if (!RB_TYPE_P(hash, T_HASH))
rb_raise(rb_eTypeError, "non-hash given");
}
for (i = 0; i <= T_MASK; i++) {
counts[i] = 0;
}
for (i = 0; i < heap_allocated_pages; i++) {
struct heap_page *page = heap_pages_sorted[i];
RVALUE *p, *pend;
p = page->start; pend = p + page->total_slots;
for (;p < pend; p++) {
void *poisoned = asan_poisoned_object_p((VALUE)p);
asan_unpoison_object((VALUE)p, false);
if (p->as.basic.flags) {
counts[BUILTIN_TYPE(p)]++;
}
else {
freed++;
}
if (poisoned) {
GC_ASSERT(BUILTIN_TYPE((VALUE)p) == T_NONE);
asan_poison_object((VALUE)p);
}
}
total += page->total_slots;
}
if (hash == Qnil) {
hash = rb_hash_new();
}
else if (!RHASH_EMPTY_P(hash)) {
rb_hash_stlike_foreach(hash, set_zero, hash);
}
rb_hash_aset(hash, ID2SYM(rb_intern("TOTAL")), SIZET2NUM(total));
rb_hash_aset(hash, ID2SYM(rb_intern("FREE")), SIZET2NUM(freed));
for (i = 0; i <= T_MASK; i++) {
VALUE type = type_sym(i);
if (counts[i])
rb_hash_aset(hash, type, SIZET2NUM(counts[i]));
}
return hash;
}
|
#define_finalizer(obj, aProc = proc()) ⇒ Object (private)
Adds aProc as a finalizer, to be called after obj was destroyed. The object ID of the obj will be passed as an argument to aProc. If aProc is a lambda or method, make sure it can be called with a single argument.
3231 3232 3233 3234 3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 3245 3246 |
# File 'gc.c', line 3231
static VALUE
define_final(int argc, VALUE *argv, VALUE os)
{
VALUE obj, block;
rb_scan_args(argc, argv, "11", &obj, &block);
should_be_finalizable(obj);
if (argc == 1) {
block = rb_block_proc();
}
else {
should_be_callable(block);
}
return define_final0(obj, block);
}
|
#each_object([) {|obj| ... } ⇒ Integer (private) #each_object([) ⇒ Object (private)
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.
If no block is given, an enumerator is returned instead.
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
3166 3167 3168 3169 3170 3171 3172 3173 3174 |
# File 'gc.c', line 3166
static VALUE
os_each_obj(int argc, VALUE *argv, VALUE os)
{
VALUE of;
of = (!rb_check_arity(argc, 0, 1) ? 0 : argv[0]);
RETURN_ENUMERATOR(os, 1, &of);
return os_obj_of(of);
}
|
#undefine_finalizer(obj) ⇒ Object (private)
Removes all finalizers for obj.
3184 3185 3186 3187 3188 |
# File 'gc.c', line 3184
static VALUE
undefine_final(VALUE os, VALUE obj)
{
return rb_undefine_finalizer(obj);
}
|