The
internals of Java memory model depends on which JVM is used, though at high
level things are similar. There are two main memory regions in the JVM - the heap and the stack. Local variables and methods reside on the stack, everything else on the heap.
How many types of memory areas are allocated by JVM?
Many types:
- Class(Method) Area
- Heap
- Stack
- Program Counter Register
- Native Method Stack
Internal Architecture of JVM
Let's understand the internal architecture of JVM. It contains classloader, memory area, execution engine etc.
|
1) Classloader
Classloader is a subsystem of JVM that is used to load class files.
2) Class(Method) Area
Class(Method) Area stores per-class structures such as the runtime constant pool, field and method data, the code for methods.
3) Heap
It is the runtime data area in which objects are allocated.
4) Stack
Java Stack stores frames.It holds local variables and partial results, and plays a part in method invocation and return.
|
Each thread has a private JVM stack, created at the same time as thread.
|
A new frame is created each time a method is invoked. A frame is destroyed when its method invocation completes.
|
5) Program Counter Register
PC (program counter) register. It contains the address of the Java virtual machine instruction currently being executed.
6) Native Method Stack
It contains all the native methods used in the application.
7) Execution Engine
It contains:
|
1) A virtual processor
|
2) Interpreter: Read bytecode stream then execute the instructions.
|
3) Just-In-Time(JIT) compiler: It is used to improve the performance.JIT compiles parts of the byte code that have similar functionality at the same time, and hence reduces the amount of time needed for compilation.Here the term ?compiler? refers to a translator from the instruction set of a Java virtual machine (JVM) to the instruction set of a specific CPU.
Java Garbage Collection
In
java, garbage means unreferenced objects.
Garbage
Collection is process of reclaiming the runtime unused memory automatically. In
other words, it is a way to destroy the unused objects.
There
are methods like System.gc() and Runtime.gc() which is used
to send request of Garbage collection to JVM but it’s not guaranteed that
garbage collection will happen.
If
there is no memory space for creating a new object in Heap Java Virtual Machine
throws OutOfMemoryError.
Generally,
an object becomes eligible for garbage collection in Java on following cases:
1) All references to that object explicitly set to null e.g. object = null 2) The object is created inside a block and reference goes out scope once control exit that block. 3) Parent object set to null if an object holds the reference to another object and when you set container object's reference null, child or contained object automatically becomes eligible for garbage collection.
Advantage of Garbage Collection
Heap
Generations for Garbage Collection in Java
|
Java objects are created in Heap and Heap is divided
into three parts or generations for the sake of garbage collection in Java.
- Young Generation
(Eden and Survivor space)
- Old Generation
(Tenured Space)
- Permanent Generation
(permGen)
Young
Generation is further divided into
- Eden space
- S0 (survivor space)
- S1 (survivor space)
Young
Generation
Eden
space is a place where new objects are created. When the space is filled up to
a certain percentage, GC is performed. This event is called as Minor GC.
The
surviving objects from Eden space are moved to survivor spaces (S0 & S1).
Minor
GC checks the object in survivor spaces and move to other survivor spaces
(S0->S1).
Objects
surviving multiple minor GC are moved to old generation.
Old
Generation
Objects
survived multiple minor GC are moved to old generation. When an old generation
is full, the major GC takes place to remove the unused objects. This event can
cause a minor pause in the working of application. Too many frequent major GC
can trigger performance issue in the application. While designing an
application, one should be considerate about it.
Perm
Gen
Perm
Gen contains the metadata of the classes.
- Methods of a class
(including the bytecodes)
- Names of the classes
(in the form of an object that points to a string also in the permanent
generation)
- Constant pool (e.g
String pool) information (data read from the class file, see chapter 4 of
the JVM specification for all the details).
- Object arrays and
type arrays associated with a class (e.g., an object array containing
references to methods).
- Internal objects
created by the JVM (java/lang/Object or java/lang/exception for instance)
When
does an object becomes eligible for GC.
- When a object is not
referred by other objects or all its references are set to null.
- Object moves out of
the scope.
- Weak reference
objects, such as WeakHashMap
Note:
With Java 8 Perm gen is removed completely. Its replaced by Metaspace.
Note: Java
programmer cannot force the GC from program using System.gc() or
Runtime.gc()
Where Java static variables are stored in memory?
Static member variables are stored in Permanent
Generation area of heap. The reason is because static doesn’t belong to the
object but to the class, so it’s considered as part of class definition.
What is difference between permGen and Metaspace?
In Java 8, permGen is replaced by Metaspace.
There are many difference between them, the major two being:
There are many difference between them, the major two being:
- Metaspace can expand at runtime.
- Metaspace is part of Native memory whereas permGen is part of heap.
What are different type of
Garbage collector?
- Serial GC
(-XX:+UseSerialGC): Serial GC uses the simple
mark-sweep-compact approach for young and old generations garbage
collection i.e Minor and Major GC. Serial GC is useful in client-machines
such as our simple standalone applications and machines with smaller CPU.
It is good for smaller applications with low memory footprint.
- Parallel GC
(-XX:+UseParallelGC): Parallel GC is same as Serial
GC except that is spawns N threads for young generation garbage collection
where N is the number of CPU cores in the system. We can control the
number of threads using -XX:ParallelGCThreads=n JVM option. Parallel
Garbage Collector is also called throughput collector because it uses
multiple CPUs to speed up the GC performance. Parallel GC uses single
thread for Old Generation garbage collection.
- Parallel Old GC
(-XX:+UseParallelOldGC): This is same as
Parallel GC except that it uses multiple threads for both Young Generation
and Old Generation garbage collection.
- Concurrent Mark
Sweep (CMS) Collector (-XX:+UseConcMarkSweepGC):
CMS Collector is also referred as concurrent low pause collector. It does
the garbage collection for Old generation. CMS collector tries to minimize
the pauses due to garbage collection by doing most of the garbage
collection work concurrently with the application threads. CMS collector
on young generation uses the same algorithm as that of the parallel
collector. This garbage collector is suitable for responsive applications
where we cannot afford longer pause times. We can limit the number of
threads in CMS collector using -XX:ParallelCMSThreads=n JVM option.
- G1 Garbage Collector
(-XX:+UseG1GC): The Garbage First or G1 garbage
collector is available from Java 7 and it̢۪s long term goal is to replace
the CMS collector. The G1 collector is a parallel, concurrent, and incrementally
compacting low-pause garbage collector. Garbage First Collector doesn't
work like other collectors and there is no concept of Young and Old
generation space. It divides the heap space into multiple equal-sized heap
regions.
What is java.lang.OutOfMemoryError in Java
OutOfMemoryError
in Java is a subclass of java.lang.VirtualMachineErrorand JVM
throws java.lang.OutOfMemoryError when it ran out of memory in the
heap. OutOfMemoryError in Java can come anytime in heap mostly while you
try to create an object and there is not enough space on the heap to allocate
that object
Types
of OutOfMemoryError
Having
this memory architecture in mind also helps to understand the different
OutOfMemoryErrors like:
- Exception in thread
“main”: java.lang.OutOfMemoryError:
Java heap space
Reason: an object could not be allocated into the heap space. - Exception in thread
“main”: java.lang.OutOfMemoryError:
PermGen space
Reason: classes and methods could not be loaded into the PermGen space. This occurs when an application requires a lot of classes e.g. in various 3rd party libraries. - Exception in thread
“main”: java.lang.OutOfMemoryError:
Requested array size exceeds VM
limit
Reason: this occurs when an arrays is created larger than the heap size. - Exception in thread
“main”: java.lang.OutOfMemoryError:
request bytes for . Out of swap space?
Reason: this occurs when an allocation from the native heap failed and might be close to its limit. The indicates the source of the module where this error occurs. - Exception in thread
“main”: java.lang.OutOfMemoryError:
(Native method)
Reason: this error indicates that the problem originates from a native call rather than in the JVM.
Java Heap space:
The
JVM's heap stores all the objects generating by a running Java program. Java
uses the new operator to create objects and memory for new objects is allocated
on the heap at run time. Garbage collection is the mechanism of automatically
freeing up the memory contained by the objects that are no longer referenced by
the program.
Java Perm space:
Perm
space is used to keep information for loaded classes and few other advanced
features like String Pool(for highly optimized string equality testing), which
usually get created by String.intern() methods. As your application (number of
classes) will grow this space shall get filled quickly, since the garbage
collection on this Space is not much effective to clean up as required, you
quickly get Out of Memory : perm gen space error.
In Application server different classloaders are used to load different web applications so that you can deploy and undeploy one application without affecting other application on the same server, but while undeploying if container somehow keeps reference of any class loaded by application class loader then that class and all other related class will not be garbage collected and can quickly fill the PermGen space if you deploy and undeploy your application many times.
How to solve
java.lang.OutOfMemoryError: Java heap space
1)
An easy way to solve OutOfMemoryError in java is to increase the maximum heap size by using JVM options
"-Xmx512M", this will immediately solve your OutOfMemoryError. This
is my preferred solution when I get OutOfMemoryError in Eclipse, Maven or ANT
while building project because based upon size of project you can easily run
out of Memory.here is an example of increasing maximum heap size of JVM,
Also its better to keep -Xmx to -Xms ration either 1:1 or
1:1.5 if you are setting heap size in your java application
export JVM_ARGS="-Xms1024m -Xmx1024m"
2) The second way to resolve OutOfMemoryError in Java is rather hard and comes when you don't have much memory and even after increase maximum heap size you are still getting java.lang.OutOfMemoryError, in this case, you probably want to profile your application and look for any memory leak. You can use Eclipse Memory Analyzer to examine your heap dump or you can use any profiler like Netbeans or JProbe. This is tough solution and requires some time to analyze and find memory leaks.
export JVM_ARGS="-Xms1024m -Xmx1024m"
2) The second way to resolve OutOfMemoryError in Java is rather hard and comes when you don't have much memory and even after increase maximum heap size you are still getting java.lang.OutOfMemoryError, in this case, you probably want to profile your application and look for any memory leak. You can use Eclipse Memory Analyzer to examine your heap dump or you can use any profiler like Netbeans or JProbe. This is tough solution and requires some time to analyze and find memory leaks.
How to solve
java.lang.OutOfMemoryError: PermGen space
To
fix this OutOfMemoryError in Java, you need to increase heap size of Perm space by using JVM
option "-XX: MaxPermSize". You can also
specify initial size of Perm space by using "-XX:
PermSize" and keeping both initial and maximum Perm Space you
can prevent some full garbage collection which may occur when Perm Space gets
re-sized. Here is how you can specify initial and maximum Perm size in
Java:
export JVM_ARGS="-XX:PermSize=64M -XX:MaxPermSize=256m"
export JVM_ARGS="-XX:PermSize=64M -XX:MaxPermSize=256m"
Tools to investigate and fix
OutOfMemoryError in Java
Java.lang.OutOfMemoryError
is a kind of error which needs a lot of investigation to find out the root
cause of the problem, which object is taking memory, how much memory it is
taking or finding dreaded memory leak and you can't do this without having knowledge
of available tools in java space. Here I am listing out some free tools which
can be used to analyze heap and will help you to find culprit of
OutOfMemoryError
1) Visualgc
Visualgc
stands for Visual Garbage Collection Monitoring Tool and you can attach it to
your instrumented hotspot JVM. The main strength of visualgc is that it
displays all key data graphically including class loader, garbage collection,
and JVM compiler performance data.
The
target JVM is identified by its virtual machine identifier also called as vmid.
You can read more about visualgc and vmid options here.
2)
Jmap
Jmap
is a command line utility comes with JDK6 and allows you to take a memory dump
of the heap in a file. It’s easy to use as shown below:
jmap
-dump:format=b,file=heapdump 6054
Here
file specifies the name of memory dump file which is "heap dump" and
6054 is PID of your Java progress. You can find the PDI by using "ps -ef”
or windows task manager or by using the tool called "jps"(Java Virtual
Machine Process Status Tool).
3)
Jhat
Jhat
was earlier known as hat (heap analyzer tool) but it is now part of JDK6. You
can use jhat to analyze heap dump file created by using "jmap".
Jhat is also a command line utility and you can run it from cmd window as shown
below:
jhat
-J-Xmx256m heapdump
Here
it will analyze memory dump contained in file "heapdump". When you
start jhat it will read this heap dump file and then start
listening on HTTP port, just point your browser into port where jhat is listening
by default 7000 and then you can start analyzing objects present in heap dump.
4)
Eclipse memory analyzer
Eclipse
memory analyzer (MAT) is a tool from eclipse foundation to analyze java heap
dump. It helps to find classloader leaks and memory leaks and helps to minimize
memory consumption. You can use MAT to analyze heap dump carrying millions of
object and it also helps you to extract suspect of memory leak.
No comments:
Post a Comment