mirror of
https://github.com/ruby/ruby.git
synced 2026-01-26 12:14:51 +00:00
Fix memory leak in cloning complex imemo_fields
When we clone a complex imemo_fields, it calls creates the imemo_fields
using rb_imemo_fields_new_complex, which allocates and initializes a new
st_table. However, st_replace will directly replace any exisiting fields
in the st_table, causing it to leak.
For example, this script demonstrates the leak:
obj = Class.new
8.times do |i|
obj.instance_variable_set(:"@test#{i}", nil)
obj.remove_instance_variable(:"@test#{i}")
end
obj.instance_variable_set(:"@test", 1)
10.times do
100_000.times do
obj.dup
end
puts `ps -o rss= -p #{$$}`
end
Before:
26320
39296
52320
63136
75520
87008
97856
114800
120864
133504
After:
16288
20112
20416
20720
20800
20864
21184
21424
21904
21904
This commit is contained in:
parent
5179b7fb3f
commit
3ec597f619
9
imemo.c
9
imemo.c
@ -167,11 +167,14 @@ rb_imemo_fields_clone(VALUE fields_obj)
|
||||
VALUE clone;
|
||||
|
||||
if (rb_shape_too_complex_p(shape_id)) {
|
||||
clone = rb_imemo_fields_new_complex(rb_imemo_fields_owner(fields_obj), 0);
|
||||
RBASIC_SET_SHAPE_ID(clone, shape_id);
|
||||
st_table *src_table = rb_imemo_fields_complex_tbl(fields_obj);
|
||||
st_table *dest_table = rb_imemo_fields_complex_tbl(clone);
|
||||
|
||||
st_table *dest_table = xcalloc(1, sizeof(st_table));
|
||||
clone = rb_imemo_fields_new_complex_tbl(rb_imemo_fields_owner(fields_obj), dest_table);
|
||||
|
||||
st_replace(dest_table, src_table);
|
||||
RBASIC_SET_SHAPE_ID(clone, shape_id);
|
||||
|
||||
st_foreach(dest_table, imemo_fields_complex_wb_i, (st_data_t)clone);
|
||||
}
|
||||
else {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user