End of Life Ruby 3.1 has reached end of life and gets no more fixes. Switch to Ruby 4.0 →
class method
ObjectSpace.count_objects
ObjectSpace.count_objects([result_hash]) → hash
gc.c
View on GitHub ↗
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];
short stride = page->slot_size;
uintptr_t p = (uintptr_t)page->start;
uintptr_t pend = p + page->total_slots * stride;
for (;p < pend; p += stride) {
VALUE vp = (VALUE)p;
GC_ASSERT((NUM_IN_PAGE(vp) * sizeof(RVALUE)) % page->slot_size == 0);
void *poisoned = asan_poisoned_object_p(vp);
asan_unpoison_object(vp, false);
if (RANY(p)->as.basic.flags) {
counts[BUILTIN_TYPE(vp)]++;
}
else {
freed++;
}
if (poisoned) {
GC_ASSERT(BUILTIN_TYPE(vp) == T_NONE);
asan_poison_object(vp);
}
}
total += page->total_slots;
}
if (NIL_P(hash)) {
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;
}
Counts all objects grouped by type.
It returns a hash, such as:
Example
{
: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.
Example
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.
See also
.count_nodes
.count_objects_size
.count_imemo_objects
.count_symbols
also in
4.1 · 4.0 · 3.4 · 3.3 · 3.2 · 3.0