Explain how the Java Virtual Machine (JVM) manages memory, specifically focusing on garbage collection and heap vs. stack allocation.