@@ -126,6 +126,7 @@ class PluginVersionWorking
126126 end
127127
128128 def try_plugin ( plugin , successful_dependencies )
129+ Bundler ::DepProxy . __clear!
129130 builder = Bundler ::Dsl . new
130131 gemfile = LogStash ::Gemfile . new ( File . new ( LogStash ::Environment ::GEMFILE_PATH , "r+" ) ) . load
131132 gemfile . update ( plugin )
@@ -203,6 +204,29 @@ task :generate_plugins_version do
203204 end
204205 end
205206 end
207+ DepProxy . class_eval do
208+ # Bundler caches it's dep-proxy objects (which contain Gem::Dependency objects) from all resolutions.
209+ # The Hash itself continues to grow between dependency resolutions and hold up a lot of memory, to avoid
210+ # the issue we expose a way of clear-ing the cached objects before each plugin resolution.
211+ def self . __clear!
212+ @proxies . clear
213+ end
214+ end
215+
216+ Fetcher ::CompactIndex . class_eval do
217+ alias_method :__bundle_worker , :bundle_worker
218+ # The compact index is built using multiple threads and this is hard-coded atm to 25 threads:
219+ # `Bundler::Worker.new(Bundler.current_ruby.rbx? ? 1 : 25, worker_name, func)`
220+ # each thread might built up a Bundler::Source::Rubygems object which retains more than 100MB.
221+ # By limiting the worker thread count we make sure not to produce too many of these objects.
222+ def bundle_worker ( func = nil )
223+ __bundle_worker ( func ) . tap do |worker |
224+ size = worker . instance_variable_get ( :@size )
225+ fail ( "@size = #{ size . inspect } is no longer an integer" ) unless size . is_a? ( Integer )
226+ worker . instance_variable_set ( :@size , 2 )
227+ end
228+ end
229+ end
206230 end
207231
208232 PluginVersionWorking . new . generate
0 commit comments