Closed peterzhu2118 closed 3 months ago
When an exception is raised, it can leak memory in head. There are two places that can leak memory:
head
Check_Type(tuple, T_ARRAY)
tuple
StringValue(name)
StringValue(value)
to_str
This commit fixes these memory leaks by wrapping the code around a rb_ensure so that the memory is freed in all cases.
The following code demonstrates the memory leak:
emitter = Psych::Emitter.new(StringIO.new) nil_to_string_tags = [[nil, "tag:TALOS"]] + ([1] * 1000) expected_array_tags = [1] * 1000 10.times do 1_000.times do # Raises `no implicit conversion of nil into String` emitter.start_document([], nil_to_string_tags, 0) rescue TypeError end 1_000.times do # Raises `wrong argument type Integer (expected Array)` emitter.start_document([], expected_array_tags, 0) rescue TypeError end puts `ps -o rss= -p #{$$}` end
Before:
47248 79728 111968 144224 176480 208896 241104 273280 305472 337664
After:
14832 15088 15344 15344 15360 15632 15632 15632 15648 15648
When an exception is raised, it can leak memory in
head
. There are two places that can leak memory:Check_Type(tuple, T_ARRAY)
can leak memory iftuple
is not an array.StringValue(name)
andStringValue(value)
if they are not strings and the call toto_str
does not return a string.This commit fixes these memory leaks by wrapping the code around a rb_ensure so that the memory is freed in all cases.
The following code demonstrates the memory leak:
Before:
After: