You're welcome -- glad to help.
I should note that I am assuming that with 16GB of RAM you're running a 64-bit OS. If you're running a 32-bit OS (with PAE to access all the extra memory), you're going to be more constrained. While an OS with PAE can access quite a lot of RAM, 32-bit processes are still limited to a 32-bit virtual memory space (with a maximum addressable memory of 4GB, but functionally less on some OS's depending on whether or not they do things like mapping kernel memory into process memory space (Windows, I'm looking at you...)). On some OS's, Java also expects that the heap memory space will be completely contiguous (virtually, not physically), which may not seem like a problem until you run into a virus scanner or some such that loads some library resident into every single process ("DLL Injection") at the 2GB mark or some other fixed virtual memory location below the maximum (yeah, I'm looking at Windows again. Had this one bite a customer pretty badly a few years back who for some odd reason still insisted on running 32-bit Windows servers). 64-bit OS's can still support DLL Injection, but typically the injected memory location is so insanely high within VM (quite a large amount higher than you can physically install in your typical system), that it doesn't cause any problems.
The point being (before I go off into too long of a rant), on the off chance you're still running a 32-bit OS and 32-bit Java (I'm reasonably sure you can run 64-bit Java on OS X 1.6, even when booting with the 32-bit kernel), tuning may only take you so far for Java applications that are really memory hungry -- you'll still hit a wall well before even 1/4 of your installed RAM is used. In that case, upgrading to a 64-bit OS and 64-bit Java is highly recommended, if possible.
(As an aside, this is actually one reason why Android handset developers were quick to jump into using quad-core processors. When programming Android using Java, all of these memory and garbage collection issues arise, in a package with less RAM and less processing power than a standard PC. The best way to handle being able to create responsive applications under GC in such a model is to do as much of the GC as you can in the background on one or more independent cores to minimize whole-application pauses. Contract this to iOS which uses retain/release cycles (or better yet, Automatic Retain Counting, aka ARC) where memory management is either hand-coded by the developer, or resolved at compile time (in the case of ARC), requiring no GC at all).
Yaz