What is the difference between stack memory and heap memory in Java?
The stack holds local variables and the frames of running methods. Each time you call a method, the JVM pushes a frame containing that method's parameters, its local variables and the bookkeeping needed to return; when the method returns, the frame is popped and its memory is reclaimed immediately. The stack is fast, thread-local and self-managing, and its size is fixed by the thread stack size, usually a megabyte or so per thread.
The heap holds all objects — every instance you create with new, every array, every String, every collection. The heap is shared between threads, it is managed by the garbage collector, and its size is governed by the maximum heap size passed to the JVM. Nothing in your source code decides where an object lives; the only thing that lives on the stack is the reference variable pointing at it.
The consequence worth internalising is that the reference and the object are in different places. A local variable of a reference type is a slot on the stack holding an address; the object it addresses lives on the heap. That is why a method can hand you a reference to an object and then lose its own reference to it — the object is still alive as long as your reference keeps it reachable.
One clarification that interviewers often probe: primitives declared as locals also live in the stack frame, and their values are copied on every call, so reassigning a local primitive has no effect outside the method. Primitive fields are different — they live inside the heap object that declares them.