How to fixed PermGen memory issue - java

I got the following error in browser when log into the system
java.lang.RuntimeException: javax.servlet.ServletException:
java.lang.OutOfMemoryError: PermGen space
com.opensymphony.sitemesh.webapp.decorator.BaseWebAppDecorator.render(BaseWebAppDecorator.java:39)
com.opensymphony.sitemesh.webapp.SiteMeshFilter.doFilter(SiteMeshFilter.java:84)

java.lang.OutOfMemoryError
Thrown when the Java Virtual Machine cannot allocate an object because
it is out of memory, and no more memory could be made available by the
garbage collector. OutOfMemoryError objects may be constructed by the
virtual machine as if suppression were disabled and/or the stack trace
was not writable.
Increase the heap size of your JVM
It is possible to increase heap size allocated by the JVM by using command line options Here we have 3 options
-Xms<size> set initial Java heap size
-Xmx<size> set maximum Java heap size
-Xss<size> set java thread stack size
Common causes of OutofMemory in PermGen is ClassLoader. Whenever a class is loaded into JVM, all its meta data, along with Classloader, is kept on PermGen area and they will be garbage collected when the Classloader which loaded them is ready for garbage collection. In Case Classloader has a memory leak than all classes loaded by it will remain in memory and cause permGen outofmemory once you repeat it a couple of times.
Now there are two ways to solve this:
1. Find the cause of Memory Leak or if there is any memory leak.
2. Increase size of PermGen Space by using JVM param -XX:MaxPermSize and -XX:PermSize.

java.lang.OutOfMemoryError: PermGen space
Two step solution.
Step One : Alter your application launch configuration and add (or increase if present) the -XX:MaxPermSize parameter . This is a temporary step as if this is a live system most probably the extra memory will also get filled at some time in the future.But this will fix the error for now.
Step two : Release unnecessary resources. Make sure all database connections are closed. Load and unload classes judiciously.restructure you program to work with small amounts of data at a time. Analyse and Fix memory leaks

Either optimize your program or increase java heap size with run time parameters.(-Xxx)

It is important to know, whether the PermGenError occurs after every depolyment, or after few ones.
If it is the first case, just increase the memory size for your PermGen.
If it is the second, you have some dead cows in your code. In this case, increasing memory size will only postpone the error, as your memory is still growing in size after every deployment. You have to profile your app like for example with jvisualvm (here is nice tutorial) and find some dead cows. It is important to understand, that PermGenError is not about the classes itself, but about classLoaders (Classloader leaks: the dreaded "java.lang.OutOfMemoryError: PermGen space" exception).
In my case (Glssfish server), the problem was the Log4j2 libs added to the web app. I had to add them also to the server libs (domain-dir/lib), so that according to the Glassfish Class Loaders Hierarchy they where loaded by the Common classLoader.

Related

IntelliJ Idea error: Unable to import maven project: See logs for details [duplicate]

I am getting the following error on execution of a multi-threading program
java.lang.OutOfMemoryError: Java heap space
The above error occured in one of the threads.
Upto my knowledge, Heap space is occupied by instance variables only. If this is correct, then why this error occurred after running fine for sometime as space for instance variables are alloted at the time of object creation.
Is there any way to increase the heap space?
What changes should I made to my program so that It will grab less heap space?
If you want to increase your heap space, you can use java -Xms<initial heap size> -Xmx<maximum heap size> on the command line. By default, the values are based on the JRE version and system configuration. You can find out more about the VM options on the Java website.
However, I would recommend profiling your application to find out why your heap size is being eaten. NetBeans has a very good profiler included with it. I believe it uses the jvisualvm under the hood. With a profiler, you can try to find where many objects are being created, when objects get garbage collected, and more.
1.- Yes, but it pretty much refers to the whole memory used by your program.
2.- Yes see Java VM options
-Xms<size> set initial Java heap size
-Xmx<size> set maximum Java heap size
Ie
java -Xmx2g assign 2 gigabytes of ram as maximum to your app
But you should see if you don't have a memory leak first.
3.- It depends on the program. Try spot memory leaks. This question would be to hard to answer. Lately you can profile using JConsole to try to find out where your memory is going to
You may want to look at this site to learn more about memory in the JVM:
http://developer.streamezzo.com/content/learn/articles/optimization-heap-memory-usage
I have found it useful to use visualgc to watch how the different parts of the memory model is filling up, to determine what to change.
It is difficult to determine which part of memory was filled up, hence visualgc, as you may want to just change the part that is having a problem, rather than just say,
Fine! I will give 1G of RAM to the JVM.
Try to be more precise about what you are doing, in the long run you will probably find the program better for it.
To determine where the memory leak may be you can use unit tests for that, by testing what was the memory before the test, and after, and if there is too big a change then you may want to examine it, but, you need to do the check while your test is still running.
You can get your heap memory size through below programe.
public class GetHeapSize {
public static void main(String[] args) {
long heapsize = Runtime.getRuntime().totalMemory();
System.out.println("heapsize is :: " + heapsize);
}
}
then accordingly you can increase heap size also by using:
java -Xmx2g
http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html
To increase the heap size you can use the -Xmx argument when starting Java; e.g.
-Xmx256M
Upto my knowledge, Heap space is occupied by instance variables only. If this is correct, then why this error occurred after running fine for sometime as space for instance variables are alloted at the time of object creation.
That means you are creating more objects in your application over a period of time continuously. New objects will be stored in heap memory and that's the reason for growth in heap memory.
Heap not only contains instance variables. It will store all non-primitive data types ( Objects). These objects life time may be short (method block) or long (till the object is referenced in your application)
Is there any way to increase the heap space?
Yes. Have a look at this oracle article for more details.
There are two parameters for setting the heap size:
-Xms:, which sets the initial and minimum heap size
-Xmx:, which sets the maximum heap size
What changes should I made to my program so that It will grab less heap space?
It depends on your application.
Set the maximum heap memory as per your application requirement
Don't cause memory leaks in your application
If you find memory leaks in your application, find the root cause with help of profiling tools like MAT, Visual VM , jconsole etc. Once you find the root cause, fix the leaks.
Important notes from oracle article
Cause: The detail message Java heap space indicates object could not be allocated in the Java heap. This error does not necessarily imply a memory leak.
Possible reasons:
Improper configuration ( not allocating sufficiant memory)
Application is unintentionally holding references to objects and this prevents the objects from being garbage collected
Applications that make excessive use of finalizers. If a class has a finalize method, then objects of that type do not have their space reclaimed at garbage collection time. If the finalizer thread cannot keep up, with the finalization queue, then the Java heap could fill up and this type of OutOfMemoryError exception would be thrown.
On a different note, use better Garbage collection algorithms ( CMS or G1GC)
Have a look at this question for understanding G1GC
In most of the cases, the code is not optimized. Release those objects which you think shall not be needed further. Avoid creation of objects in your loop each time. Try to use caches. I don't know how your application is doing. But In programming, one rule of normal life applies as well
Prevention is better than cure. "Don't create unnecessary objects"
Local variables are located on the stack. Heap space is occupied by objects.
You can use the -Xmx option.
Basically heap space is used up everytime you allocate a new object with new and freed some time after the object is no longer referenced. So make sure that you don't keep references to objects that you no longer need.
No, I think you are thinking of stack space. Heap space is occupied by objects. The way to increase it is -Xmx256m, replacing the 256 with the amount you need on the command line.
To avoid that exception, if you are using JUnit and Spring try adding this in every test class:
#DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
I have tried all Solutions but nothing worked from above solutions
Solution: In My case I was using 4GB RAM and due to that RAM usage comes out 98% so the required amount if Memory wasn't available. Please do look for this also.If such issue comes upgrade RAM and it will work fine.
Hope this will save someone Time
In netbeans, Go to 'Run' toolbar, --> 'Set Project Configuration' --> 'Customise' --> 'run' of its popped up windo --> 'VM Option' --> fill in '-Xms2048m -Xmx2048m'. It could solve heap size problem.

Why is my Java heap dump size much smaller than used memory?

Problem
We are trying to find the culprit of a big memory leak in our web application. We have pretty limited experience with finding a memory leak, but we found out how to make a java heap dump using jmap and analyze it in Eclipse MAT.
However, with our application using 56/60GB memory, the heap dump is only 16GB in size and is even less in Eclipse MAT.
Context
Our server uses Wildfly 8.2.0 on Ubuntu 14.04 for our java application, whose process uses 95% of the available memory. When making the dump, our buffers/cache used space was at 56GB.
We used the following command to create the dump: sudo -u {application user} jmap -dump:file=/mnt/heapdump/dump_prd.bin {pid}
The heap dump file size is 16,4GB and when analyzing it with Eclipse MAT, it says there are around 1GB live objects and ~14,8GB unreachable/shallow heap.
EDIT: Here is some more info about the problem we see happening. We monitor our memory usage, and we see it grow and grow, until there is ~300mb free memory left. Then it stays around that amount of memory, until the process crashes, unfortunately without error in the application log.
This makes us assume it is a hard OOM error because this only happens when the memory is near-depleted. We use the settings -Xms25000m -Xmx40000m for our JVM.
Question
Basically, we are wondering why the majority of our memory isn't captured in this dump. The top retained size classes don't look too suspicious, so we are wondering if there is something heap dump-related what we are doing wrong.
When dumping its heap, the JVM will first run a garbage collection cycle to free any unreachable objects.
How can I take a heap dump on Java 5 without garbage collecting first?
In my experience, in a true OutOfMemoryError where your application is simply demanding more heap space than is available, this GC is a fool's errand and the final heap dump will be the size of the max. heap size.
When the heap dump is much smaller, that means the system was not truly out of memory, but perhaps had memory pressure. For example, there is the java.lang.OutOfMemoryError: GC overhead limit exceeded error, which means that the JVM may have been able to free enough memory to service some new allocation request, but it had to spend too much time collecting garbage.
It's also possible that you don't have a memory problem. What makes you think you do? You didn't mention anything about heap usage or an OutOfMemoryError. You've only mentioned the JVM's memory footprint on the operating system.
In my experience, having a heap dump much smaller than the real memory used can be due to a leak in the JNI.
Despite you don't use directly any native code, there are certain libraries that use it to speed up.
In our case, it was a Deflater and Inflater not properly ended.

How to identify the issue when Java OutOfMemoryError?

How to identify the issue when java OutOfMemoryError or stackoverflow comes in production. By which reason it is coming or why the server is down.
For example I am developing an application which is lived on production and UAT. Instantly on production java OutOfMemoryError or stackoverflow.
Then how can we track this issue, by which reason it has happened ? Is there any technique that can tell me by which code flow this is happening ?
Please explain it. I have faced this issue many times.
If you face it in production and you cannot really reason about it from stacktraces or logs, you need to analyze what was in there.
Get the VM to dump on OOM
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath="/tmp"
And use that for analysis. The memory analyzer tool (http://eclipse.org/mat/) is a good standalone program for this analysis.
The Oracle docs:- Troubleshooting Memory Leaks has detailed explanation on it:
This error is thrown when there is insufficient space to allocate an
object in the Java heap or in a particular area of the heap. The
garbage collector cannot make any further space available to
accommodate a new object, and the heap cannot be expanded further.
.....
An early step to diagnose an OutOfMemoryError is to determine what the
error means. Does it mean that the Java heap is full, or does it mean
that the native heap is full? To help you answer this question, the
following subsections explain some of the possible error messages,
with reference to the detail part of the message:
Exception in thread "main": java.lang.OutOfMemoryError: Java heap
space
See 3.1.1 Detail Message: Java heap space.
Exception in thread "main": java.lang.OutOfMemoryError: PermGen space
See 3.1.2 Detail Message: PermGen space.
Exception in thread "main": java.lang.OutOfMemoryError: Requested
array size exceeds VM limit
See 3.1.3 Detail Message: Requested array size exceeds VM limit.
Exception in thread "main": java.lang.OutOfMemoryError: request
bytes for . Out of swap space?
See 3.1.4 Detail Message: request bytes for . Out of
swap space?.
Exception in thread "main": java.lang.OutOfMemoryError:
(Native method)
See 3.1.5 Detail Message: (Native method).
UPDATE:-
You can download the HotSpot VM source code from OpenJDK. If you want to monitor and track the memory footprint of your Java Heap spaces ie, the young generation and old generation spaces is to enable verbose GC from your HotSpot VM. You may add the following parameters within your JVM start-up arguments:
-verbose:gc –XX:+PrintGCDetails –XX:+PrintGCTimeStamps –Xloggc:<app path>/gc.log
You can use jvisualvm to manage your process at the runtime.
You can see memory, heap space, objects etc ...
This program is located in your bin directory of your JDK.
It's best to try to reproduce the problem in place where you are free to debug it - on dev server or on your local machine. Then try to debug, look for recursive invocations, heap size and what objects are being created. Unfortunately it's not always easy to reproduce prod env (with it's load and so on) on local machine, therefore finding the root cause of such error might be a challenge.
The amount of memory given to Java process is specified at startup. memory divided into separate areas, heap and permgen being the most familiar sub-areas.
While you specify the maximum size of the heap allowed for this particular process via -Xmx,
the corresponding parameter for permgen is -XX:MaxPermSize. 90% of the Java apps seem to require between 64 and 512 MB of permgen to work properly. In order to find your limits, experiment a bit.
to solve this issue you have change your VM arguments
-Xms256m -Xmx1024m -XX:+DisableExplicitGC -Dcom.sun.management.jmxremote
-XX:PermSize=256m -XX:MaxPermSize=512m
add above two line in VM argument i am sure you will not face this problem any more
to know more about go to OutOfMemory
Low memory configuration :-
It is possible that you have estimate less memory for your application for example your application need 2 Gb of memory but you have configured only 512 Mb so here you will get an OOME(Out-of-memory errors )
Due to Memoryleak :-
Memory leak is responsible for decreasing the available memory for heap and can lead to out of memory error for more read What is a Memory Leak in java?
Memory fragmentation :-
It is possible that there may be space in heap but it may be not contiguous . And heap needs compaction . Rearrange its memory.
Excess GC overhead :-
Some JVM implementations, such as the Oracle HotSpot, will throw an out-of-memory error when GC overhead becomes too great. This feature is designed to prevent near-constant garbage collection—for example, spending more than 90% of execution time on garbage collection while freeing less than 2% of memory. Configuring a larger heap is most likely to fix this issue, but if not you’ll need to analyze memory usage using a heap dump
Allocating over-sized temporary objects:-
Program logic that attempts to allocate overly large temporary objects. Since the JVM can’t satisfy the request, an out-of-memory error is triggered and the transaction will be aborted. This can be difficult to diagnose, as no heap dump or allocation-analysis tool will highlight the problem. You can only identify the area of code triggering the error, and once discovered, fix or remove the cause of the problem.
for more pls visit my site
http://all-about-java-and-weblogic-server.blogspot.com/2014/02/main-causes-of-out-of-memory-errors-in.html

Weblogic memory leak on deploy undeploy

Weblogic 10.3.5 running with 32 bit JRockit R 28.2.4-14 using -Xmx1024m -Xms1024m always gets out of native memory after 5-8 Undeploy-Redeploy cycles of our Java EE EAR files.
According to the error message and what is displayed in VisualVM, it is not the Java Heap that gets too full but insufficient system memory which is available.
java.lang.OutOfMemoryError: class allocation, 865324184 loaded, 464M footprint,
in check_alloc (src/jvm/model/classload/classalloc.c:215).
Attempting to allocate 1G bytes
There is insufficient native memory for the Java
Runtime Environment to continue.
Possible reasons:
The system is out of physical RAM or swap space
In 32 bit mode, the process size limit was hit
Possible solutions:
Reduce memory load on the system
Increase physical memory or swap space
Check if swap backing store is full
Use 64 bit Java on a 64 bit OS
Decrease Java heap size (-Xmx/-Xms)
Decrease number of Java threads
Decrease Java thread stack sizes (-Xss)
Disable compressed references (-XXcompressedRefs=false)
at sun.misc.Unsafe.defineClass(Native Method)
at sun.reflect.ClassDefiner.defineClass(ClassDefiner.java:45)
at sun.reflect.MethodAccessorGenerator$1.run(MethodAccessorGenerator.java:381)
at sun.reflect.MethodAccessorGenerator.generate(MethodAccessorGenerator.java:377)
at sun.reflect.MethodAccessorGenerator.generateSerializationConstructor(MethodAccessorGenerator.java:95)
at sun.reflect.ReflectionFactory.newConstructorForSerialization(ReflectionFactory.java:313)
at java.io.ObjectStreamClass.getSerializableConstructor(ObjectStreamClass.java:1322)
I understand the possible solutions that are suggested, but as everything is fine if the application is only deployed once, it seems classes are not correctly freed when undeploying. A heap dump after undeployment shows there are many of our classes left in memory. Shouldn't they be garbage collected then?
The path to GC Root shows a Thread <JNI Local> java.lang.Thread # 0x129ac778 JDWP Transport Listener: dt_socket Native Stack, Thread. There is no traffic on the server and I don't know why this stays to be active.
This memory leak is most likely caused in the perm-gen space (this is how it's called on Hotspot JVM). JRockit doesnt have dedicated Perm-Gen space, but uses "regular" heap space for this.
Have a look at the following sites which I found really helpful for understanding what's happening here:
What is a PermGen leak
Busting PermGen Myths
I find Eclipse MAT very helpful for debugging PermGen leaks:
My approach is usually something like this:
Do a heap dump after undeployment
Find one of you application classes (doesn't really matter which, all should leak). Alternatively display duplicate classes.
Display the path to the GC root
Why the fix looks like depends on the cause.
Most likely some classes are holding to the classloader which causes the full application to leak on redeploy. You can read about this article about classloaders.

Java Heap Space - How does -Xmx work exactly?

I have encountered the infamous OutOfMemoryException in my application and instead of simply increasing the amount of Heap Space available I tried to look into what the problem was, just in case, there was some sort of leak from my application.
I added the JVM parameter -XX:+HeapDumpOnOutOfMemoryError which creates a Heap Dump when the OutOfMemory Error is encountered. I then analysed the dump file produced with different profiling tools. I then started playing around with the -Xmx parameter and observing patterns.
What puzzled me is the following. Why is it that on analyzing the dump I found that the total size of all objects was much less than the total that I set using the -Xmx parameter?
For example, say I set the -Xmx to '2048m'. When I analyzed the dump file I found a total of 400Mb of objects on the Heap. I was expecting to find 2GB. Am I missing something?
My guess is that since modern GCs partition the heap into separate memory areas (young / tenured / permanent generations), it is enough for the permanent generation space to fill up completely for an out of memory error to occur. You can configure the ratio of different generation spaces using various JVM command line options.
Here is a good article about Tuning Garbage Collection with the 5.0 Java[tm] Virtual Machine (I couldn't find a more recent one but I think the basics still apply in newer VMs).
Re-read your error message - it may tell you which type of memory you ran out of. I'd guess that it was PermGen space. Permgen is used for class definitions (amongst other things). You can tune the space for PermGen via -XX:MaxPermSize PermGen isn't part of the heap, so isn't included in heap dump.
See this answer for more information on looking at PermGen.
If this isn't the issue, then try setting your initial heap size (-Xms) to the same as the maximum. Doing this means that the heap won't grow which should make understanding what's going on easier.
I recommend using jvisualvm (part of the JDK) to look at your memory utilisation as your program runs.

Categories

Resources