Skip to content

Commit 6721ec2

Browse files
committed
Include free_immediately: false in heap dumps
This adds "free_immediately: false" to the heap dump for any T_DATA which doesn't specify RUBY_TYPED_FREE_IMMEDIATELY. These are the objects which end up as T_ZOMBIE and will have their dfree callback deferred to later when the program is running holding the GVL. This is useful to include because there is more overhead to freeing these objects, and it's worth knowing how many there are.
1 parent b1220ac commit 6721ec2

2 files changed

Lines changed: 20 additions & 1 deletion

File tree

ext/objspace/objspace_dump.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -574,9 +574,14 @@ dump_object(VALUE obj, struct dump_config *dc)
574574

575575
case T_DATA:
576576
if (RTYPEDDATA_P(obj)) {
577+
const rb_data_type_t *type = RTYPEDDATA_TYPE(obj);
577578
dump_append(dc, ", \"struct\":\"");
578-
dump_append(dc, RTYPEDDATA_TYPE(obj)->wrap_struct_name);
579+
dump_append(dc, type->wrap_struct_name);
579580
dump_append(dc, "\"");
581+
if (!(type->flags & RUBY_TYPED_FREE_IMMEDIATELY) &&
582+
type->function.dfree != RUBY_DEFAULT_FREE) {
583+
dump_append(dc, ", \"free_immediately\":false");
584+
}
580585
}
581586
break;
582587

test/objspace/test_objspace.rb

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1021,6 +1021,20 @@ def test_escape_class_name
10211021
assert_equal class_name, JSON.parse(json)["name"]
10221022
end
10231023

1024+
def test_dump_free_immediately
1025+
require '-test-/typeddata'
1026+
1027+
# Bug::TypedData has flags=0 (no FREE_IMMEDIATELY)
1028+
info = ObjectSpace.dump(Bug::TypedData.new)
1029+
assert_include(info, '"struct":"typed_data"')
1030+
assert_include(info, '"free_immediately":false')
1031+
1032+
# Most typed data objects have FREE_IMMEDIATELY, so the field should be absent
1033+
info = ObjectSpace.dump(Thread.current.group)
1034+
assert_include(info, '"struct":"thgroup"')
1035+
assert_not_include(info, '"free_immediately"')
1036+
end
1037+
10241038
def test_dump_include_shareable
10251039
omit 'Not provided by mmtk' if RUBY_DESCRIPTION.include?("+GC[mmtk]")
10261040

0 commit comments

Comments
 (0)