kubo / ruby-oci8

Ruby-oci8 - Oracle interface for ruby
Other
169 stars 75 forks source link

Huge memory usage starting with version 2.2.7 #230

Open edlebert opened 3 years ago

edlebert commented 3 years ago

A feature was added in 2.2.7 to help with network round trips for LOBs by utilizing array fetching, if the table has a LOB. This is creating BindTypes for all the columns in the query with a max_array_size == 100. According to memory_profiler, those BindType objects are taking up a lot of space (hundreds of megabytes in my Ruby on Rails app). The memory appears to not be freed either, so it's some sort of cached memory.

Is there a way to disable this feature?

kubo commented 3 years ago

Is there a way to disable this feature?

How about adding the following monkey patch after require "oci8"?

class OCI8
  class Cursor
    private
    alias_method :define_one_column_orig, :define_one_column
    def define_one_column(pos, param)
      @fetch_array_size = nil # disable array fetching anytime
      define_one_column_orig(pos, param) # call original
    end
  end
end
einjohn commented 2 years ago

At our company we were having the same problem – using ruby-oci8 at 2.2.9.

Without disabling this feature, like suggested above, we saw an increase in memory consumption by 1.5 gigabytes after sequentially requesting just 100 objects from the database (using ransack); and another 1.5 gig increase with the next 100 requests … and so on and so forth.

With this feature disabled, we could easily request several thousand objects (using the otherwise exact same code; also sequentially and also using ransack) from the database and end up with an increase of a mere 300 megabytes – compared to the freshly launched app.

Szemethym commented 1 year ago

We have also noticed a huge decrease in memory usage after putting in the suggested monkey patch. @kubo Would you consider adding it as a configurable option, so there's no need for said patch?