Overview of Java Virtual Machine
The Java Virtual Machine (JVM) is the platform upon which programs run. JVM is built/created for that specific operating system and architecture, and sits between the operating system and any compiled programs or applications.
Java programs are compiled (using javac) into bytecode. This is interpreted by the JVM into the specific instructions for that architecture and operating system.Regardless of the platform on which Java code was compiled, it can run on any JVM of the same or later version.
How is memory allocated?
The new keyword allocates memory on the Java heap. The heap is the main pool of memory, accessible to the whole of the application. If there is not enough memory available to allocate for that object, the JVM attempts to reclaim some memory from the heap with a garbage collection.If it still cannot obtain enough memory, an OutOfMemoryError is thrown, and the JVM exits. The heap is split into several different sections, called generations. As objects survive more garbage collections, they are promoted into different generations.
The older generations are not garbage collected as often. Because these objects have already proven to be longer lived, they are less likely to be garbage collected.
When objects are first constructed, they are allocated in the Eden Space. If they survive a garbage collection, they are promoted to Survivor Space, and they live long there, and they are allocated to the Tenured Generation. This generation is garbage collected much less frequently.
There is also a fourth generation, called the Permanent Generation, or PermGen. The objects that reside here are not eligible to be garbage collected, and usually contain an immutable state necessary for the JVM to run, such as class definitions and the String constant pool.
Note that the PermGen space is removed from Java 8, and replaced with a new space called Metaspace, which will be held in native memory.
What is garbage collection?
Garbage collection is the mechanism of reclaiming previously allocated memory, and it can be reused by future memory allocations. In Java, whenever a new object is constructed, commonly by the new keyword, the JVM allocates an appropriate amount of memory for that object and the data it holds.
When that object is no longer needed, the JVM needs to reclaim that memory, so other constructed objects can use it. More modern languages, such as Java and C#, have an automatic system for this, taking the effort, and any potential mistakes, away from the programmer.
Several different algorithms for garbage collection exist, but they all have the same goal of finding allocated memory that is no longer referenced by live code, and return that to a pool of available memory for future allocations.
The traditional garbage collection algorithm in Java is called mark-and-sweep. Each and every object reference in running code is marked as a live, each and every reference within that object is traversed and also marked as live, and so on, until all routes from live objects have been traced.
Once this is complete, each object in the heap is visited, and those memory locations not marked as live are made available for allocation. During this process, all of the threads in the JVM are paused to allow the memory to be reclaimed, known as stop the world. So naturally, the garbage collector tries to minimize the amount of time this takes.
There have been several iterations of the garbage collection algorithm since Java was first released, with as more of the work done in parallel as possible. Java 6 introduced a new algorithm, called Garbage First (G1). It was approved for test use in Java6, and production use in Java 7. G1 concentrates on a mark-and-sweep algorithm, running in parallel, while it concentrates on areas of mainly empty memory first in an attempt to keep large areas of free space available.
Other operations are also performed during garbage collection, such as promotion to different generations, and grouping repeatedly accessed objects by moving the objects around withinmemory to try to retain as much free space as possible. This is called compaction. Compaction takes place while the JVM is in its stop-the-world phase, as live objects are potentially moving to different physical memory locations.