How does the Java Virtual Machine (JVM) handle garbage collection, and how do you tune it for performance?