Low Cost Grails / Java Web Hosting - How much server memory do you need?
If you want to get your Grails or Java web application up and running on a dedricated or virtual server (vServer), chances are high that you experience the frustrating "Could not reserve enough space for object heap" barrier. Let us first calculate just how much memory your application needs so you are able to choose the right server for your application(s). We develop some formulars which help you in your calculation.
Measuring Grails / Java web application memory consumption
Your Java web application on the vServer will be your productive version, so you'll need a development environment which should be as similiar as possible. Since vServer hosting takes place on a paravirtualized Linux kernel with a Linux distribution, your development environment should be Linux, preferable with the same distribution and bit-size (x86-32bit vs. x86-64bit). If you develop on Windows, you could use VMware or a comparable virtualization software, which has the added advantage, that you may restrict the amount of main memory of the virtual box to the same amount like some vServer offerings. We''ll use this development environment to benchmark the memory requirements in advance.
I assume your Grails/Java web application exists on Linux: Start your application (grails run-app) and search for the java process with its memory requirements:
> ps -ux | grep java
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 9431 0.0 1.6 417444 137968 ? Sl Oct27 18:06 /usr/lib/jvm/java-1.5.0-sun[..]
The important values are VSZ and RSS ones. VSZ is the maximum memory the java application will ever use and reserve from the operation system at startup. RSS is the current memory in use. The difference between VSZ and RSS is the free memory available to your java application. Your application should never push RSS near VSZ or out-of-memory exceptions will happen and crash your application and/or the java virtual machine. In this example the JVM reserves 407m of memory, but actually uses 134m. The maximum heap space given was 192m specified by the JVM argument "-Xmx192m" at startup. Notice that the JVM needs more memory than the heap space. How do you calculate the best heap space value?
Calculating maximum heap space
I assume that you want to give as much memory as possible to your java web application(s).
My experiments gave the following results on 32-Bit Linux with the Sun Java 5 JVM and the "-client" argument:
Starting with any given maxHeapSize ("-XmxmaxHeapSizem"), measure the VSS memory requirement in megabyte. Base memory requirement is then calculated as
baseMem = VSS - maxHeapSize - (maxHeapSize / 32)
Now take the total amount of memory of your server environment serverMem, substract the memory consumption of all over processes (usedMem), substract some buffer memory for processes which have to run additionally like ssh logins, web logfile analyzers, spam filters, etc. (bufferMem), which gives us
VSSOpt = serverMem - usedMem - bufferMem
At last the maximum Heap Size is calculated as the difference of the memory consumption of the JVM process minus the base memory requirement multiplied with a corrective factor of 32/33 (You could also set the factor to 1 without loosing to much precision):
optMaxHeapSize = (32/33) * (VSSOpt - baseMem)
Example
Lets assume a server environment with 512m and a Java web application with a VSS of 348412 at "-client -Xmx128m") maximum heap size setting. VSS equals to 340m.
baseMem = 340 - 128 - (128/32) = 208
VSSOpt = 512m - 50m - 50m = 412m
optMaxHeapSize = (32/33) * (412m - 208m) = 198m
Since 198m is greater than 128m and your Java web application runs fine at 128m heap space all should run well on your server.
Memory requirements of a minimal Grails application
As a benchmark of a minimal Grails application I took the 'tutor' example from the Groovy-in-Action (GINA) Book with the two domain classes TutorialEntry and Author and pure scaffolding (any other Book-Author or Racalist-.Race example will do). The baseMem of this application is about 208m. It does not run with 16m of heap space, but does work with 32m and more. This gives us a VSS of 208 + 32 + 32/32 = 241m. The system processes require in my minimized setting 43m and we should plan for a minimum of 20m of memory for temporary processes so we need at least 304m of main memory.
Summary
Lets face it: Java (and Groovy and Grails) are memory hogs. You will run into problems trying to run your Grails or Java web application in a server with 256m main memory (swap want help you since Java is not really swap friendly). The next level of vServer / vps offerings start at 256m + 128m = 384m of minimum ram, which you should go for. If you want to get olympic and press your application into 256m nevertheless, take into account the amount of time and knowledge you need to succeed and the savings you'll get in return. I guess it's not worth it.
In the next blog entry I will dive deeper into the amount of main memory you'll have in your vServer / vps and where the difference between guaranteed memory and FlexRAM is.
