PERF: ensure we run full GC on contexts

PERF: ensure we run full GC on contexts

Prior to this change we would never clear memory from contexts and rely on V8 reacting to pressure

This could lead to bloating of PrettyText and Transpiler contexts

This optimisations ensures that we will clear memory 2 seconds after the last eval on the context

diff --git a/Gemfile.lock b/Gemfile.lock
index ce187c8..2a195ee 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -188,7 +188,7 @@ GEM
     method_source (1.0.0)
     mini_mime (1.0.2)
     mini_portile2 (2.4.0)
-    mini_racer (0.2.11)
+    mini_racer (0.2.14)
       libv8 (> 7.3)
     mini_scheduler (0.12.2)
       sidekiq
diff --git a/lib/discourse_js_processor.rb b/lib/discourse_js_processor.rb
index 94e39d0..df5e35c 100644
--- a/lib/discourse_js_processor.rb
+++ b/lib/discourse_js_processor.rb
@@ -79,7 +79,7 @@ class DiscourseJsProcessor
 
     def self.create_new_context
       # timeout any eval that takes longer than 15 seconds
-      ctx = MiniRacer::Context.new(timeout: 15000)
+      ctx = MiniRacer::Context.new(timeout: 15000, ensure_gc_after_idle: 2000)
       ctx.eval("var self = this; #{File.read("#{Rails.root}/vendor/assets/javascripts/babel.js")}")
       ctx.eval(File.read(Ember::Source.bundled_path_for('ember-template-compiler.js')))
       ctx.eval("module = {}; exports = {};")
diff --git a/lib/js_locale_helper.rb b/lib/js_locale_helper.rb
index 99d344e..8864eca 100644
--- a/lib/js_locale_helper.rb
+++ b/lib/js_locale_helper.rb
@@ -282,7 +282,7 @@ module JsLocaleHelper
   def self.with_context
     @mutex.synchronize do
       yield @ctx ||= begin
-        ctx = MiniRacer::Context.new(timeout: 15000)
+        ctx = MiniRacer::Context.new(timeout: 15000, ensure_gc_after_idle: 2000)
         ctx.load("#{Rails.root}/lib/javascripts/messageformat.js")
         ctx
       end
diff --git a/lib/pretty_text.rb b/lib/pretty_text.rb
index 1e4775d..0f114c5 100644
--- a/lib/pretty_text.rb
+++ b/lib/pretty_text.rb
@@ -65,7 +65,7 @@ module PrettyText
   end
 
   def self.create_es6_context
-    ctx = MiniRacer::Context.new(timeout: 25000)
+    ctx = MiniRacer::Context.new(timeout: 25000, ensure_gc_after_idle: 2000)
 
     ctx.eval("window = {}; window.devicePixelRatio = 2;") # hack to make code think stuff is retina
 

GitHub sha: 4601833e

2 Likes

Impact of the change in production :confetti_ball:

(dotted vertical line is the deploy)

Has enormous impact on V8 memory used, significant impact on memory usage per process and per container!

2 Likes