yosiat / panko_serializer

High Performance JSON Serialization for ActiveRecord & Ruby Objects
https://panko.dev
MIT License
592 stars 36 forks source link

Fix memory leak which caused by exception #132

Closed Watson1978 closed 1 year ago

Watson1978 commented 1 year ago

When it invoked Data_Wrap_Struct(), Ruby's GC can release allocated memory properly. However, we have to manage the memory ourselves until invoking Data_Wrap_Struct().

Check_Type() will raise an exception if the argument is not a string, and memory leak will be caused by the exception.

So, I think ALLOC() should be called after Check_Type().

You will see an increase memory usage with attached test code.

Before

0, 19.3828125 MB
5000, 20.19140625 MB
10000, 20.70703125 MB
15000, 21.22265625 MB
20000, 21.73828125 MB
25000, 22.25390625 MB
30000, 22.76953125 MB

After

0, 19.359375 MB
5000, 19.90234375 MB
10000, 19.90234375 MB
15000, 19.90234375 MB
20000, 19.90234375 MB
25000, 19.90234375 MB
30000, 19.90234375 MB

Test code

require 'panko_serializer'

30_001.times do |i|
  Panko::Association.new(123, 456, 789) rescue nil
  Panko::Attribute.new(123456789) rescue nil

  rss = Integer(`ps -o rss= -p #{Process.pid}`) / 1024.0
  puts "#{i}, #{rss} MB" if i % 5000 == 0
end
Watson1978 commented 1 year ago

Similar with https://github.com/ohler55/oj/pull/865