Skip to content

Commit

Permalink
Fix memory leak with ruby/require/autoload_paths
Browse files Browse the repository at this point in the history
In ruby versions less than 2.5.0, it was found that if you have
Pathname objects in the $LOAD_PATH instead of regular strings, it messes
with ruby's internals and causes a memory leak.

In most ruby applications, this wouldn't be much of an issue, but there
are a significant number of deferred require statements that we do in
manageiq that cause this to leak overtime.  Further more, this seems to
be an issue that presents itself even if the file has been loaded
previously (mostly a no-op for require).

Replication of this issue can be done using a simple ruby script:

    require 'pathname'
    require 'fileutils'

    puts Process.pid

    Dir.mkdir("foo") unless Dir.exists?("foo")
    $LOAD_PATH.unshift(Pathname.new("foo"))

    FileUtils.touch("empty.rb")
    1500.times { 1500.times { require "empty" }; print "."; GC.start; }

By simply running the application with the Pathnames converted to
strings, this should be a proper and low cost workaround for us until it
is patched in ruby or we update manageiq to >= ruby 2.5.0.
  • Loading branch information
NickLaMuro committed Jan 17, 2018
1 parent ed8eb9f commit 4fb6f0b
Showing 1 changed file with 9 additions and 9 deletions.
18 changes: 9 additions & 9 deletions config/application.rb
Original file line number Diff line number Diff line change
Expand Up @@ -90,15 +90,15 @@ class Application < Rails::Application
# Customize any additional options below...

config.autoload_paths += config.eager_load_paths
config.autoload_paths << Rails.root.join("app", "models", "aliases")
config.autoload_paths << Rails.root.join("app", "models", "mixins")
config.autoload_paths << Rails.root.join("lib", "miq_automation_engine", "models")
config.autoload_paths << Rails.root.join("lib", "miq_automation_engine", "models", "mixins")
config.autoload_paths << Rails.root.join("app", "controllers", "mixins")
config.autoload_paths << Rails.root.join("lib")
config.autoload_paths << Rails.root.join("lib", "services")

config.autoload_once_paths << Rails.root.join("lib", "vmdb", "console_methods.rb")
config.autoload_paths << Rails.root.join("app", "models", "aliases").to_s
config.autoload_paths << Rails.root.join("app", "models", "mixins").to_s
config.autoload_paths << Rails.root.join("lib", "miq_automation_engine", "models").to_s
config.autoload_paths << Rails.root.join("lib", "miq_automation_engine", "models", "mixins").to_s
config.autoload_paths << Rails.root.join("app", "controllers", "mixins").to_s
config.autoload_paths << Rails.root.join("lib").to_s
config.autoload_paths << Rails.root.join("lib", "services").to_s

config.autoload_once_paths << Rails.root.join("lib", "vmdb", "console_methods.rb").to_s

# config.eager_load_paths accepts an array of paths from which Rails will eager load on boot if cache classes is enabled.
# Defaults to every folder in the app directory of the application.
Expand Down

0 comments on commit 4fb6f0b

Please sign in to comment.