Friday, July 5, 2013

JVM Internals

Each time a Java Application is executed then an instance of JVM ,responsible for its running,is created.A JVM instance is described in terms of subsystems, memory areas, data types, and instructions.The block diagram given below,depicts a view of Internal Architecture of JVM :


While executing a Java program,a JVM requires memory for storing bytecodes,objects ,local variables,method arguments,return values,intermediate computational results and JVM does that memory management on several runtime data areas.
Each instance of the Java virtual machine has one method area and one heap. These areas are shared by all threads running inside the virtual machine. When the virtual machine loads a class file, it parses information about a type from the binary data contained in the class file. It places this type information into the method area. As the program runs, the virtual machine places all objects the program instantiates onto the heap.
A thread's Java stack stores the state of Java (not native) method which includes its local variables, the parameters with which it was invoked, its return value (if any), and intermediate calculations. The state of native method invocations is stored in an implementation-dependent way in native method stacks, in registers or other implementation-dependent memory areas.
A thread's Java stack stores the state of Java (not native) method which includes its local variables, the parameters with which it was invoked, its return value (if any), and intermediate calculations. The state of native method invocations is stored in an implementation-dependent way in native method stacks, in registers or other implementation-dependent memory areas.

Class Loader And Its Responsibilities:
The class loaders can be of two types: a bootstrap or primordial class loader and user defined class loaderEach JVM has a bootstrap class loader which loads trusted classes , including classes from Java API.JVM specs do not tell how to locate these classes and is left to implementation designers.

Heap And Stack:
The heap is the part of memory of JVM where all objects reside.
The stack is consisted of stack frames.When a thread invokes a method,the JVM pushes a new frame onto that thread's Java stack.Each stack frame is consisted of operand stack and the local variable array.All arguments,local variables,intermediate computations and return values if any are kept in these stack corresponding to the method invoked.The stack frame on the top of the stack is called the active stack frame,which is the current place of execution.When the method completes, the virtual machine pops and discards the frame for that method.

How Java Program executes inside JVM:
When JVM executes a Java application, a runtime instance of JVM is born.This runtime instance invoke main() method of Java application.The main() method of an application serves as the starting point for that application's initial thread. The initial thread can in turn fire off other threads.

This thread has a program counter(PC) and Java stack.Whenever main() method is invoked, a stack frame is pushed onto the stack,this then becomes the active tack frame.The program counter in the new Java stack frame will point to the beginning of the method.

There is only one heap corresponding to an instance of JVM and all objects created are stored here.This heap is shared by all threads created in an application.

Inside the Java virtual machine, threads come in two flavors: daemon and non- daemon. A daemon thread is ordinarily a thread used by the virtual machine itself, such as a thread that performs garbage collection. The application, however, can mark any threads it creates as daemon threads. The initial thread of an application--the one that begins at main()--is a non- daemon thread.

A Java application continues to execute (the virtual machine instance continues to live) as long as any non-daemon threads are still running. When all non-daemon threads of a Java application terminate, the virtual machine instance will exit. If permitted by the security manager, the application can also cause its own demise by invoking the exit() method of class Runtime or System.

When main() returns,it terminates the application's only non-daemon thread, which causes the virtual machine instance to exit. 

How JVM performs Thread synchronization:
JVM associates a lock with an object or a class to achieve mutilthreading. A lock is like a token or privilege that only one thread can "possess" at any one time.
The JVM uses locks in conjunction with monitors. A monitor is basically a guardian in that it watches over a sequence of code, making sure only one thread at a time executes the code.Each monitor is associated with an object reference. It is the responsibility of monitor to watch an arriving thread must obtain a lock on the referenced object.
In Java language terminology, the coordination of multiple threads that must access shared data is called synchronization. The language provides two built-in ways to synchronize access to data: with synchronized statements or synchronized methods.
For an instance method, the JVM acquires the lock associated with the object upon which the method is being invoked. For a class method, it acquires the lock associated with the class to which the method belongs. After a synchronized method completes, whether it completes by returning or by throwing an exception, the lock is released.
Two opcodes, monitorenter and monitorexit are used by JVM for accomplishing this task.

How JVM performs Garbage Collection:
Whenever a reference to an object on heap lies dangling or no longer in use by an active program then it becomes eligible for being garbage collected by JVM.JVM specifications do not force any specific kind of garbage collection algorithm though there are several algorithms like reference counting,tracing,compacting,copying,generational etc. in place.
Try using -Xaprof to get a profile of the allocations (objects and sizes) of your application.

Also try -agentlib:hprof=heap=all (or other option, try -agentlib:hprof=help for a list) 

An application has running lot of threads and running out of memory.WHY?:
You may be running into a problem with the default stack size for threads. In Java SE 6, the default on Sparc is 512k in the 32-bit VM, and 1024k in the 64-bit VM. On x86 Solaris/Linux it is 320k in the 32-bit VM and 1024k in the 64-bit VM.

On Windows, the default thread stack size is read from the binary (java.exe). As of Java SE 6, this value is 320k in the 32-bit VM and 1024k in the 64-bit VM.

You can reduce your stack size by running with the -Xss option. For example:

java -server -Xss64k

Note that on some versions of Windows, the OS may round up thread stack sizes using very coarse granularity. If the requested size is less than the default size by 1K or more, the stack size is rounded up to the default; otherwise, the stack size is rounded up to a multiple of 1 MB.

64k is the least amount of stack space allowed per thread.

Difference between JRE, JVM and JDK:
A Java Runtime Environment (JRE) is a prerequisite for running Java applications on any computer.A JRE contains a Java Virtual Machine(JVM),all standard,core java classes and runtime libraries. It does not contain any development tools such as compiler, debugger, etc. JDK(Java Development Kit) is a whole package required to Java Development which essentially contains JRE+JVM,and tools required to compile and debug,execute Java applications.

No comments:

Post a Comment