Repeatedly creating and throwing out objects carries very little performance overhead, but holding onto existing object instances for reuse creates significant work for the garbage collector.
Reference counting is simple, but requires significant assistance from the compiler and imposes overhead on the mutator (the term for the user program, from the perspective of the garbage collector).
The second technique is to reduce the polling overhead of the JMX exposed memory pools further by implementing the listening collector pattern instead of a polling pattern.