In our test environment we have a lot of apps spread out over a few servers and Glassfish domains. To make versioning easier I would have liked to have one Glassfish domain per customer per app (kind of like a heavyweight version of lots of jetty instances).
I have heard that Glassfish is resource-intensive, so I would like to measure approximately how many instances would fit in the available RAM. I know I can do this by starting the instances and watching top
output, but which specific statistics should I be concentrating on to get a good measure of resource consumption per instance?
Using
top
to determine memory requirements is more an art than an exact science. There are two primary ways to go about it.In both cases you want to take a baseline of the system's resource usage before you start the program you're investigating (in your case GlassFish). Then you follow one of two paths:
Aggregate Memory Usage Path
This is the way I personally do it because I feel it gives a better picture of overall resource utilization.
Also if you mess up you'll probably wind up with a bigger number rather than a smaller one.
top
in a terminal somewhere and note the header output.Pay special attention to Active and Wired memory:
Active
+wired
) and free (Free
) memory.In this case, used memory went up by 161MB ((447+233)-(606+235)), and free memory decreased by 158MB.
(All other things being equal these numbers should be equal or very close, the difference being made up by changes in the other fields like Inactive memory or Buffer space).
Repeat the above for additional instances of the program you're investigating and plot the change on a graph to determine the trend/curve.
Individual Instance Memory Usage Path
This method examines the individual process(es) associated with the program you're investigating.
Proceed as above, except rather than looking at the
top
output's header look at the individual processes that are spawned when you launch the program (I'll use Postgres as my example):Total up the resident (
RES
) size for each process associated with your application and note that as the RAM used. (the difference between resident size and the virtual size (VSIZE
, or justSIZE
).There are some caveats with this method:
Size Inflation or Deflation
RES
ident size doesn't tell the whole story: Shared libraries get loaded, and these aren't counted in resident size, so if you total up resident size as I said above your number will be below the actual utilization.Shared libraries ARE counted in virtual size, (
VIRT
or just plainSIZE
), but they get counted against every program using them, so if you total up virtual size your number will be above the actual utilization -- often significantly above.Some versions of
top
also split out Swap separately -- If your program has a memory leak (or a lot of data that goes stale and gets swapped out) this can also skew your figures.Missing Processes
If you don't count all the processes associated that are spawned as a result of starting your program your total RAM usage figure will be lower than actual.
Finally there is one caveat that applies to both of these methods: Dynamic applications will mess with your numbers.
By that I mean that a program like Postgres, or Apache that either spawns new threads or new child processes to service user requests will not give an accurate picture under static conditions: You need to put a working load on the program so you can measure the impact of workload on the system (this is another reason I find the aggregate path easier: You don't have to hunt down all the children, you can just read the header as you ramp up the workload).
Ideally you will put a very heavy load on the server during testing to ensure that normal production loads won't make it start thrashing its swap space. Also once you've done your sizing you should always add some cushion RAM (I use 10% over and above the worst case operating results) and ensure that your system has enough RAM to handle that as a peak load condition.
Remember: RAM is cheap and downtime is expensive. You can always throw more RAM at the problem during server build-out and the marginal cost will likely be lower than having to shut down a system to add RAM later.
Note that all my
top
output is from FreeBSD -- Your specific labeling may differ. Consult the man page fortop
on your system to figure out the appropriate fields.