The answer is twelve (check out StringBuffer if you want to learn more) [1]. Twelve objects for a tiny little trace message! Allocating memory on the heap for just one of those objects is actually quite costly. It may not look like much, but the new statement is an expensive operation. Java objects aren't small either. The minimum size depends on what JVM you're running. If you're very lucky you might get away with a minimum of 18 - 20 bytes, but more typically the minimum object size is 40 bytes. And remember that's the minimum overhead the JVM requires ... actual data will be extra! Big objects are bad because they chew up virtual memory, swamp your valuable memory bandwidth (the most limited hardware resource in current machines), pollute your CPU cache and force the garbage collector to do more work. With our little snippet above, all 12 objects have to be allocated on the heap, those big 40 byte headers have to be filled out with all the information the JVM requires, then the data is copied in, they get used briefly, and then they're discarded. But of course they don't go away immediately. Oh no, they hang around until the garbage collector finally catches them.
And all that takes time.
In a tight loop, even a handful of unnecessary object creations can blow out a big chunk of memory and cost you a lot of time. What kind of tight loop? Well how about the rendering loop called every frame in your Java3D application.
The answer is to be very careful about how and when you create objects. Take particular note of where you use new and where you work with strings. Where possible you should pre-allocate and recycle your objects: get the memory once and then reuse it. If you always work with a fixed number of objects each don't allocate them every frame, allocate them once before the first frame has started. For Java3D code Point, Matrix and Vector are ideal candidates for this treatment[2]. Working in 3D inevitably involves matrix and vector manipulation. If you allocate your matrices every frame then you'll burn memory, waste cache and force the garbage collector to do much more work (see tip #4). Much cheaper to call setIdentity than to create a new object every time you need a fresh matrix.