jruby/jruby — pull request #2188 by cheald (2014-11-13 07:27:39+00:00)
Title: Rework the Regexp cache to be a simple WeakHashMap

This means that cache keys are shorter-lived than the SoftReferences used before, but it will
allow for the rapid expiration of memory-hungry one-shot regexes as well.

Implemented per discussion with @headius in IRC.

Testing with the following script demonstrates the pathological case in master, and the much improved handling with the WeakRefCache:

require 'benchmark'
Benchmark.bm do |x|
x.report("regexp creation") do
count = 0
2000.times do |i|
str = "test#{i}" * 5
Regexp.new(str)
i.times do |j|
Regexp.new(str)
Regexp.new("test#{i * j}" * 5)
end
print "."
end
end
end

I think the issue here is that when there are a large number of keys in the caches, the overhead of the actual ConcurrentHashMap currently used to back the cache becomes prohibitive and starves the JRuby process. This results in something like this (and JRuby either stalls or crashes once it gets into this boundary behavior):

![](http://i.imgur.com/5NJHl4E.png)

However, with the WeakHashMap cache, behavior is more like this (and the test finishes in ~9 sec):

![](http://i.imgur.com/4wDBWOd.png)

Fixes #2078