Skip to content

Instantly share code, notes, and snippets.

@DavidAntaramian
Last active December 2, 2015 21:26
Show Gist options
  • Save DavidAntaramian/b7621baa5325c66aac02 to your computer and use it in GitHub Desktop.
Save DavidAntaramian/b7621baa5325c66aac02 to your computer and use it in GitHub Desktop.
Forcing JRuby garbage collection for Sidekiq
require 'java'
module App
module Middleware
# Middleware for forcing run of the garbage collector after a task
# finishes. A "server," in this case, is any code that is overseeing
# the processing of an asynchronous queue.
class SidekiqGarbageCollector
# Garbage collection will only be forced if the amount of
# memory used exceeds this constant (represented as bytes in
# base 2). See #memory_threshold_met? for more info on how this
# constant is applied
MEMORY_THRESHOLD = 1024 * 1024 * 512 # => 512 MB (base-2)
# @return [java.lang.Runtime] A reference to the environment
# runtime object
attr_reader :runtime
# Creates a new SidekiqGarbageCollector instance
#
# @param [Hash] options A hash of options to configure the
# SidekiqServerLogger instance. Should be `nil`
def initialize(options=nil)
@runtime = java.lang.Runtime.get_runtime
end
# Called by Sidekiq when a job is being processed
#
# @param [#perform] worker An instance of the worker class
# which will actually process this job
# @param [Hash] msg Hash of arguments which will be passed to
# #perform on the worker instance
# @queue [String] queue Name of the queue that the job is coming
# from
def call(worker, msg, queue)
yield
java.lang.System.gc() if memory_threshold_met?
end
private
# Determines whether the allocated memory is above given threshold.
# This is determined as the memory for the environment runtime,
# not just the thread this worker is running in, by subtracting
# the amount of remaining free memory reserved for the heap from
# the total memory reserved for the heap.
#
# @return [TrueClass, FalseClass] whether the memory threshold has
# been met
def memory_threshold_met?
MEMORY_THRESHOLD < runtime.total_memory - runtime.free_memory
end
end
end
end
require 'middleware/sidekiq_garbage_collector'
Sidekiq.configure_server do |config|
config.server_middleware do |chain|
chain.add App::Middleware::SidekiqGarbageCollector
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment