Skip to content

Oj::Doc.open with a block leaks memory? #990

@jdelStrother

Description

@jdelStrother

Hi there - I noticed what appears to be a memory leak when using Oj::Doc.open with a block.

From the docs it sounds like these two should be equivalent:

Oj::Doc.open(json) { }
Oj::Doc.open(json).close

If I run Oj::Doc.open(json).close in a loop, the memory usage stays stable at 28MB:

$ ruby -e 'require "oj"; json = Oj.dump((1..1000).to_a); 10000.times { Oj::Doc.open(json).close }; puts("RSS: #{`ps -o rss= -p #{Process.pid}`.to_i / 1024}MB")'
RSS: 28MB

If I pass a block and rely on that to auto-close the document, memory usage continues to grow:

$ ruby -e 'require "oj"; json = Oj.dump((1..1000).to_a); 10000.times { Oj::Doc.open(json) { } }; puts("RSS: #{`ps -o rss= -p #{Process.pid}`.to_i / 1024}MB")'
RSS: 446MB

Closing the document within the block does seem to fix the issue:

$ ruby -e 'require "oj"; json = Oj.dump((1..1000).to_a); 10000.times { Oj::Doc.open(json) { |doc| doc.close } }; puts("RSS: #{`ps -o rss= -p #{Process.pid}`.to_i / 1024}MB")'
RSS: 28MB

(Tested on macOS with ruby 3.4.8.)

It looks like fast.c comments out the free-ing code?

oj/ext/oj/fast.c

Lines 1094 to 1099 in 7355146

// TBD is this needed
/*
if (given) {
OJ_R_FREE(json);
}
*/

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions