I’ve been doing some stress testing in my project (vert.x). If you’re
not familiar with vert.x you can think of it a bit like an appserver
into which you can deploy many Ruby scripts (amongst other things).
Each Ruby script runs in its own ScriptingContainer instance and is
strictly single threaded. Each deployment should run in its own scope,
i.e. it should be isolated from any other deployments running at the
Ideally I’d like a typical app server to be able to run many thousands
of JRuby deployments.
What I notice, for a server with 2GB RAM, I can deploy around 400
deployments - my profiler reports each deployment using around 4MB RAM.
Each deployment does nothing other than require the vert.x API, this is
just a simple set of modules/classes which provides an API shim around
the vert.x Java API:
If I deploy Ruby deployments which do not require the vert.x API the
memory usage drops dramatically so I’m assuming here that the overhead
is due the generated classes for the API, and that each deployment has
its own copy of the classes.
Do you have any suggestions for reducing the memory overhead?
One thing I noticed in the profiler was there are many, many instances
of ConcurrentHashMap. I know that an empty CHM has a v. large memory
footprint (1.7kB!) compared to a regular HashMap. Since I have chosen
the scripting container to be single threaded, could a regular HashMap
be used instead?
Another thought - the vert.x API is the same for all Ruby deployments in
the server. Is there any way the classes for this could be compiled once
and somehow shared between between the different scripting containers as
opposed to each container keeping their own copy.