Skip to content

Instantly share code, notes, and snippets.

@mtjhax
Last active March 28, 2018 02:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mtjhax/92df4b277e16adfca951bf3d180c4f1a to your computer and use it in GitHub Desktop.
Save mtjhax/92df4b277e16adfca951bf3d180c4f1a to your computer and use it in GitHub Desktop.
Example using the AWS SDK v1 to demonstrate leaked memory under JRuby 9.1.15.0
source 'https://rubygems.org'
gem 'aws-sdk-v1'
# Polls the AWS SimpleWorkflow service, doing nothing with the results
#
# Under JRuby 9.1.15.0 something in the AWS SDK leaks memory (a single
# instance of org.jruby.util.io.FilenoUtil builds an ever-growing
# collection of entries in the filenoMap attribute).
#
# There is no leak in earlier versions of JRuby including 9.1.14.0.
#
# HOW TO USE:
#
# 1. Get AWS credentials with access to the SimpleWorkflow service
# (access_key_id, secret_access_key, and a region to use)
#
# 2. Use bundler to install the AWS SDK gem
#
# 3. Run the program under JRuby (tested with the following settings):
# AWS_ACCESS_KEY_ID="<id>" AWS_SECRET_ACCESS_KEY="<key>" AWS_REGION=<region>
# jruby -G --server -U -J-Xmx500M -J-Xms500M -J-XX:+UseG1GC
# -J-XX:MaxGCPauseMillis=200 -J-XX:+UseStringDeduplication test.rb
#
require 'aws-sdk-v1'
AWS_CONFIG = {
access_key_id: ENV['AWS_ACCESS_KEY_ID'],
secret_access_key: ENV['AWS_SECRET_ACCESS_KEY'],
region: ENV['AWS_REGION'] || 'us-west-2'
}
SWF_DOMAIN = 'memory-leak-test-20180327'
def log(msg)
puts "#{Time.now} Thread #{Thread.current.object_id} - #{msg}"
end
def test_polling
AWS.config AWS_CONFIG
swf = AWS::SimpleWorkflow.new
domain = swf.domains[SWF_DOMAIN]
domain = swf.domains.create(SWF_DOMAIN, 1) unless domain.exists?
client = AWS::SimpleWorkflow::Client::V20120125.new
threads = []
10.times do |i|
threads << Thread.new do
log "started"
loop do
begin
client_opts = {
domain: domain.name,
identity: "memory-leak-test-20180327-thread#{i}",
task_list: { name: 'non-existent-task-list-for-test' },
maximum_page_size: 1000,
reverse_order: false
}
log "polling for SimpleWorkflow decision task"
client.poll_for_decision_task(client_opts)
log "poll complete"
rescue => e
log "rescued exception #{e}"
# avoid tight loop if poll is immediately failing
sleep 10
end
end
end
end
# wait for all threads to exit (even though they won't)
threads.each do |thread|
thread.join
end
end
test_polling
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment