ALL java object (except primitive types) are allocated on the HEAP. Creating a Class Foo instance means to allocate the 8 bytes for a Class Foo object from above (assuming that the VM uses 4 bytes to represent an integer and 4 bytes to represent a String reference. "Newing many small objects is exactly what we said is very bad for dynamic memory management. So don't think just because your objects are small allocating them costs nothing...
As a matter of fact, malloc is probably used to allocate the 8 bytes for a Class Foo object from above (assuming that the VM uses 4 bytes to represent an integer and 4 bytes to represent a String reference. You know now that malloc is expensive and so is new...
There is ABSOLUTELY no doubt that garbage collection is superior for application programming. But this does not mean that it is free or that you can't have memory leaks with a GC. And the type of GC will impact your performance dramatically. (Compare a generational GC with an non-generational GC in the context of large caches for web applicationsl...) We will discuss this in depth in our Virtual Machine session. Frequent bugs with GCs are: Forgetting static variables which hold references to large objects which reference large objects and so on... Or calling system functions which keep references to user objects without telling about: Have a look at Java ThreadGroups...
So event with Java, get a memory leak checker which will also tell you if your singletons are no singletons or how long method calls really take. Be ready for some surprises...