I just read this statement in a java book saying Objects in java reside on a heap. Is a heap used because it is the best way to store data and retrieve data fast ?
The heap is used just by the vm to allocate and deallocate blocks of memory. To access the objects there you use a reference to the block of memory (that reference is in the stack). The jvm doesn't allow direct access to the memory (like in C/C++).
Why not store objects on the stack? Well, what happens to the stack after the currently executing method stops executing?
It's an artifact of the underlying computing model. Memory to the operating system looks like a big, mostly contiguous space in which data can be read and written by address. The operating system allows processes to grab a block of memory (a large contiguous space, usually at least one page of a couple K) and to do with that as they like, by using memory addresses and read/write operations.
The java heap builds on that, i.e. to the programmer it just looks like a big bag of memory (it of course is not, i.e. garbage collection routinely moves stuff around) to which he gets "addresses" (references really, they are not actually addresses) for data (objects) written to this memory space. This allows you maximum flexibility to build more specialised data structures on top of that.
Remember that it acts like a "heap" to the programmer, because that allows you the necessary flexibility, but it doesn't have to be implemented as such. It's a piece of memory managed by the garbage collector, and there are a bunch of data structures it uses to do its job, which you could or could not consider part of the heap, i.e. it's memory used and allocated by the JVM, but usually only the memory accessible to the programmer is considered to be "the heap" in this context.
Because objects in Java often outlive the scope within which they were created, at which point the stack frame that was created for the scope ceases to exist.
Allocated heap space on the contrary is not deallocated automatically when the scope within which the object was created no longer exist.
Because Java uses a garbage collector to reclaim memory, unlike C and C++. In those languages it makes sense to use the stack for local variables*. In Java, there is no concept of a (local) variable going out of scope, only it is not referenced anymore, which makes it eligible for garbage collection (which is bound to happen sometime after that point).
* which, for the sake of clarity, does not mean that there were no heap in C/C++, or that you could not use the malloc
/new
family to allocate variables to be used solely within local scope.
Java can store objects on the stack, if it does escape analysis that determines that no references to the object are retained by non local objects when the method returns. It does not allow you to declare that an object is stored on the stack.
If Java did allow objects to be explicitly on the stack, what would happen when the method returned? What would happen to any references to the local object, held by any non local objects?
The Java designers could have decided that some references could be invalid, leading to undefined behaviour if dereferenced. Just like a pointer in C/C++. The Java designers seem to have gone to great lengths to avoid undefined behaviour.
The Java designers could have specified that all references to the local object became null. Finding all those references would be difficult. And it would result in difficult to find bugs caused by references that were assumed to be not null suddenly became null. Immutable objects containing object references would be impossible. And the notification mechanism that set references to null would have to work across threads. The cost of all this would be much higher than the advantage of local storage.
One of language designers, James Gosling, has a Lisp background, and that influence is visible in the idea that object disposal is just left to the garbage collector, with the compiler or run time environment optimising object disposal (escape analysis) if possible.