Rails 2.2

I think its (thread) safe to say things are about to get very
interesting
for JRuby.
Anyone download the RC and run some benchmarks ?

Cant wait…

Adam

AD wrote:

I think its (thread) safe to say things are about to get very
interesting for JRuby.

Anyone download the RC and run some benchmarks ?

http://guides.rubyonrails.org/2_2_release_notes.html

Cant wait…

I think it’s important to remind folks that thread safety isn’t in
itself going to improve performance; the larger benefit is a memory
reduction, since you won’t need to have multiple instances to run a
given site. But of course we do have a “cold start” issue and take some
time to warm up, so there’s a pretty good chance that reducing the
number of JRuby instances will allow the one instance to warm up faster
too…

  • Charlie

To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email

Fabio, How are you measuring memory for these tests. RSS? I suspect
this is with default JVM flag values for each web container. I
suspect if you used the same JVM flags all three web containers would
pin a similiar amount of memory. I also suspect that the default
values could be cranked down quite a bit lower in the MT 1 runtime
configuration to lower overall memory consumption.

When Nick and I did our tests we measured usage on web apps based on
heap consumed. In some sense, this is not a comprehensive use of
memory consumption, but I think it helps better illustrate how much
less memory is consumed in MT mode.

-Tom

On Mon, Oct 27, 2008 at 9:54 AM, Fabio K. [email protected]
wrote:

Jetty
The best thing is that thread-safe version allowed me to increase the number


Fabio K.
http://www.fabiokung.com

Caelum - Ensino e Inovação
http://www.caelum.com.br


Blog: http://www.bloglines.com/blog/ThomasEEnebo
Email: [email protected] , [email protected]


To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email

On Mon, Oct 27, 2008 at 1:15 PM, Thomas E Enebo [email protected]
wrote:

Fabio, How are you measuring memory for these tests. RSS?

I’m not sure if Apple’s Activity Monitor is giving me the RSS values,
but I
think it is.

I suspect this is with default JVM flag values for each web container. I
suspect if you used the same JVM flags all three web containers would
pin a similiar amount of memory.

I haven’t used the default values. My flags are: -server -Xmx1024m
-Xms512m

I also suspect that the default
values could be cranked down quite a bit lower in the MT 1 runtime
configuration to lower overall memory consumption.

Sure, you are right. I just wanted to compare with the same flags. The
default values from Apple 1.5 JVM (-Xmx64M) are enough, but the max
reply
rate was too slow, because it was spending much time with GC. Propably
the
amount of heap used by the application was in limit, forcing many Full
GCs).

Probably, -Xmx128m with one runtime would be sufficient for small Rails
applications.

When Nick and I did our tests we measured usage on web apps based on
heap consumed. In some sense, this is not a comprehensive use of
memory consumption, but I think it helps better illustrate how much
less memory is consumed in MT mode.

Agreed. I just wanted to show more “real” numbers.

Cheers,

Fabio K.

Caelum - Ensino e Inovação
http://www.caelum.com.br

I’ve made some small tests of the memory consumption in my last
presentation
at Rails Summit Latin America. Unfortunately, the slides are in pt-BR,
but
you can see them here:

The summary (for a single rails app, calculating Fibonacci, without
database
involved) is:

Tomcat
1 runtime, thread-safe: 176 MB
3 runtimes: 200 MB
5 runtimes: 244 MB

Jetty
1 runtime, thread-safe: 193 MB
3 runtimes: 204 MB
5 runtimes: 245 MB

Glassfish
1 runtime, thread-safe: 315 MB
3 runtimes: 370 MB
5 runtimes: 417 MB

These numbers reflect all the real memory that JVM had reserved in the
SO,
after some benchmark tests. My httperf flags were:

httperf --num-conns 100 --rate 10

The best thing is that thread-safe version allowed me to increase the
number
of concurrent requests, without the memory consumption growing too much.

On Sat, Oct 25, 2008 at 1:33 AM, Charles Oliver N. <
[email protected]> wrote:


To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email


Fabio K.

Caelum - Ensino e Inovação
http://www.caelum.com.br

Just a note: Since none of them used more than 512MB, and you had -Xms
512m, you likely didn’t do any full collections over the course of the
test, since the JVM would have never run out of heap space. Thus, it’s
reasonably likely that you had stuff that could have been GCed but
wasn’t because a GC wasn’t required.

Fabio K. wrote:

Agreed. I just wanted to show more “real” numbers.

Cheers,

Fabio K.
http://www.fabiokung.com

Caelum - Ensino e Inovação
http://www.caelum.com.br


To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email

Charles Oliver N. said…

… lots of fascinating things about GC wrt Java and Ruby that I would
never have found out otherwise.

Thanks for a very, very informative post, Charlie.


Cheers,
Marc


To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email

Thanks for the clarifications…more inline.

On Mon, Oct 27, 2008 at 11:57 AM, Fabio K. [email protected]
wrote:

On Mon, Oct 27, 2008 at 1:15 PM, Thomas E Enebo [email protected] wrote:

I suspect this is with default JVM flag values for each web container. I
suspect if you used the same JVM flags all three web containers would
pin a similiar amount of memory.

I haven’t used the default values. My flags are: -server -Xmx1024m -Xms512m

I wonder what glassfish is sucking in? It is a full app server and
not just a web container…perhaps it is loading more than strictly
neccesary? I know GFv3 loads packages it needs on demand now. Fabio,
are you using GFV2? Trying a preview of GFV3 would be interesting?

Probably, -Xmx128m with one runtime would be sufficient for small Rails
applications.

heh…yeah 64 Mb is probably a bit rough with the amount of object
churn…

When Nick and I did our tests we measured usage on web apps based on
heap consumed. In some sense, this is not a comprehensive use of
memory consumption, but I think it helps better illustrate how much
less memory is consumed in MT mode.

Agreed. I just wanted to show more “real” numbers.

For sure…I just wanted to make sure this was full process numbers
and not heap…

-Tom


Blog: http://www.bloglines.com/blog/ThomasEEnebo
Email: [email protected] , [email protected]


To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email

Fabio K. wrote:

Sure, you are right. I just wanted to compare with the same flags. The
default values from Apple 1.5 JVM (-Xmx64M) are enough, but the max
reply rate was too slow, because it was spending much time with GC.
Propably the amount of heap used by the application was in limit,
forcing many Full GCs).

Probably, -Xmx128m with one runtime would be sufficient for small Rails
applications.

There are a couple other important flags we’ll need to experiment with
to find the optimal sizing. First a word on generational GC…

Ruby’s GC has one big flat memory space. As a result, every GC has to be
a full GC, because it has to scan the entire memory space for dead
objects.

Hotspot and most other JVMs have generational GCs, where the heap is
split into generations of increasing age. The youngest objects are
constructed in the young generation, and most memory reclamation happens
here. Objects that survive a number of generations are promoted to older
generations (this is called tenuring).

The two coarsest-grained settings for the heap are the minimum and
maximum size (-Xms and -Xmx). With these sizes, the JVM then makes a
best guess at the sizes of the generations; for example, on the “client”
VM (non-optimizing) the young generation defaults to 1/8 the size of the
total heap. On the “server” VM (optimizing), it defaults to 1/2 or 1/4.

The sizes of the generations turn out to be very important for a
language like Ruby that has a very high rate of object churn. The risk
in having too small a young generation is that transient (short-lived)
objects may get pushed into older generations. Because even Fixnum
objects are allocated by JRuby on the heap, usually to be immediately
thrown out, we require a much larger young generation to guarantee that
short-lived objects remain short-lived. Perhaps more importantly, we may
be able to shrink the total heap size significantly if we can reduce the
size of the largely unused older generations.

There are some -XX flags for adjusting the size of the “young” or “new”
generation: -XX:NewRatio=, -XX:NewSize=,
-XX:SurvivorRatio= …and so on.

Another important setting is the tenuring rate. Because we generate a
lot of objects, there will be a lot of GC runs. If objects that are
transient get passed over by GC a few times, they may get promoted and
stick around longer than we want. So for Ruby we want a higher tenuring
threshold, to ensure we give transient objects enough time to GC.

The problem here is that we don’t know all such settings and we don’t
know the best way to tweak them for Ruby applications. Hotspot’s
defaults work well for Java, but perhaps not as well for Ruby. Hotspot
also adaptively adjusts some of these settings, but the parameters by
which it adjusts may not be appropriate for Ruby.

So the bottom line is that we’re going to need to explore the many
memory options on the JVM to come up with some recommendations. Here’s a
couple resources:

List of commonly used Hotspot options:

Complete lists of options:
http://www.md.pp.ru/~eu/jdk6options.html
http://blogs.sun.com/watt/resource/jvm-options-list.html

Java 5 GC tuning guide:

And there’s a lot more. Anyone who likes fiddling with switches finds
paradise in the JVM :slight_smile:

  • Charlie

To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email

Great explanation.
Charles (and others), have you heard anything about the new G1 garbage
collector? Can JRuby (and other dynamic languages on the JVM) benefit
from
it somehow?

On Mon, Oct 27, 2008 at 4:07 PM, Charles Oliver N. <
[email protected]> wrote:

called tenuring).
pushed into older generations. Because even Fixnum objects are allocated by
Another important setting is the tenuring rate. Because we generate a lot

To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email


Fabio K.

Caelum - Ensino e Inovação
http://www.caelum.com.br

Yes, G1 is a little different from other garbage collectors in that it
handles the age and tenuring characteristics of objects in a contuguous
memory space. So there’s no need to size the generations, twiddle
tenuring settings and so on. I haven’t had a chance to read the paper,
but ideally it’s the most adaptive GC yet created…in that it doesn’t
need to adapt nearly as much.

I’ve actually been waiting for it to get into an OpenJDK integration
release, but it’s gotten pushed back a couple times. It will probably be
in the next release (b38 I think).

G1 could be a great solution for dynlangs on the JVM since all our
transient objects will immediately be reclaimed without risking
promotion to an older generation. And since there’s not a finite set of
generations, slightly less transient objects won’t impact performance
and heap size nearly as much, since they’ll just take proportionately
longer to collect.

Good times! :slight_smile:

Fabio K. wrote:

There are a couple other important flags we'll need to experiment
promoted to older generations (this is called tenuring).
risk in having too small a young generation is that transient
Xms>, -XX:SurvivorRatio=<ratio> ...and so on.
Hotspot's defaults work well for Java, but perhaps not as well for
Complete lists of options:
- Charlie


Fabio K.
http://www.fabiokung.com

Caelum - Ensino e Inovação
http://www.caelum.com.br


To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email

Fabio K. wrote:

I’ve made some small tests of the memory consumption in my last
presentation at Rails Summit Latin America. Unfortunately, the slides
are in pt-BR, but you can see them here:

JRuby on Rails

The summary (for a single rails app, calculating Fibonacci, without
database involved) is:

I managed to get a simple app with one dumb controller with one dumb
action to start up and work pretty nicely with Xmx56M:

jruby -X-C -J-Xmx56M -J-XX:NewRatio=1 script/server -e production

I tried to do 48M but it wouldn’t start up. This is just Mongrel + Rails
2.2 + the Mongrel concurrency patch. Total memory use was around
100-110MB, holding steady.

I think we’d also have an advantage deploying multiple different Rails
apps, since we seem to be paying about a 50MB memory hit on 64-bit JVM
per process.

  • Charlie

To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email

On Mon, Oct 27, 2008 at 5:03 PM, Thomas E Enebo [email protected]
wrote:

I haven’t used the default values. My flags are: -server -Xmx1024m
-Xms512m

I wonder what glassfish is sucking in? It is a full app server and
not just a web container…perhaps it is loading more than strictly
neccesary? I know GFv3 loads packages it needs on demand now. Fabio,
are you using GFV2? Trying a preview of GFV3 would be interesting?

Yes, this is certainly the reason. I’m using Glassfish v2 and I could
disable some of the unused services, but I haven’t. I would probably
just need the Grizzly connector.


Fabio K.

Caelum - Ensino e Inovação
http://www.caelum.com.br