Gridgain: java.lang.OutOfMemoryError: GC overhead limit exceeded - java

I'm trying to set up a Gridgain cluster with 2 servers.
Load data from a .csv file (1 million to 50 million data) to the Gridgain using GridDataLoader.
Find the min, max, average, etc. from the data loaded,
When running as a standalone application in eclipse I'm getting correct output.
But while making a cluster (2 nodes in the 2 servers + 1 node inside my eclipse environment), I'm getting java.lang.OutOfMemoryError: GC overhead limit exceeded error.
The configuration file I'm using is http://pastebin.com/LUa7gxbe

Changing eclipse.ini's Xmx property might solve the problem.
Change it to -Xmx3g

java.lang.OutOfMemoryError: GC limit overhead exceeded
This error happens when the system spends too much time executing garbage collection. There can be multiple causes, it is highly related to your environment details. I don't know Gridgain. Because of your complex environment, I think about VM tuning: if your application waits for the whole memory to be full before running garbage collection, here is your main problem.
A hint can be the -XX:-UseParallelGC JVM option (some documentation is available here), but it should be the default conf in Grigain. I don't understand the proper way to configure vm options in your environment (some options seem to be related to the cache). According to the same doc, a slow network could induce a low CPU. I guess a high network could induce a high CPU (perhaps related to GC) ? To ensure you have an appropriate VM configuration, could you check the options applied when running ?

Edit the bin/ggstart.sh script, set the JVM_OPTS to a higher value.
Default is 1 GB,
Change it to
JVM_OPTS="-Xms2g -Xmx2g -server -XX:+AggressiveOpts -XX:MaxPermSize=256m"
or higher

Related

JMeter 5.1 java.lang.OutOfMemoryError: Java heap space - clear results does not help (did in 2.13)

I've recently switched from 2.13 JMeter to 5.1. In 2.13 when java gave out of memory error, I clicked Clear all button and it helped. Now in 5.1 I've got error.
ERROR:o.a.j.JMeter: Uncaught exception:
java.lang.OutOfMemoryError: Java heap space
After some runs and some data accumulated in view results tree, but clear button does not help - view results tree becomes empty but error persists and Java mission control shows heap have not been reduced. Could it be some incorrect JMeter config or?
ADDED: Thank you for heap size settings tips. It's for smoke (debug) runs, I know I can increase heap, the question is as stated about clear command behavior and possible difference between versions.
BTW, I've also tried do invoke GC jcmd <pid as reported by task manager in windows> GC.run as per How do you Force Garbage Collection from the Shell? - head was not reduced, which as I understand means JMeter does not release pointers to old java objects.
You can increase your heap size in properties file.
# This is the base heap size -- you may increase or decrease it to fit your
# system's memory availability:
HEAP="-Xms512m -Xmx512m"
Refer: https://martijndevrieze.net/2017/01/20/jmeter-tips-tricks-tip-7/
You're violating at least 2 JMeter best practices
You should use command-line non-GUI mode to run your test
You should not be using any listeners
JMeter 5.1 comes with 1 GB heap by default, you can increase JVM heap size by setting HEAP environment variable, for example the following setting will increase the heap to 2 GB:
HEAP=-Xms1024M -Xmx2048M -XX:MaxMetaspaceSize=256M

Reading huge Hive table using jdbc leads to java.lang.OutOfMemoryError: Java heap space [duplicate]

I am writing a client-side Swing application (graphical font designer) on Java 5. Recently, I am running into java.lang.OutOfMemoryError: Java heap space error because I am not being conservative on memory usage. The user can open unlimited number of files, and the program keeps the opened objects in the memory. After a quick research I found Ergonomics in the 5.0 Java Virtual Machine and others saying on Windows machine the JVM defaults max heap size as 64MB.
Given this situation, how should I deal with this constraint?
I could increase the max heap size using command line option to java, but that would require figuring out available RAM and writing some launching program or script. Besides, increasing to some finite max does not ultimately get rid of the issue.
I could rewrite some of my code to persist objects to file system frequently (using database is the same thing) to free up the memory. It could work, but it's probably a lot work too.
If you could point me to details of above ideas or some alternatives like automatic virtual memory, extending heap size dynamically, that will be great.
Ultimately you always have a finite max of heap to use no matter what platform you are running on. In Windows 32 bit this is around 2GB (not specifically heap but total amount of memory per process). It just happens that Java chooses to make the default smaller (presumably so that the programmer can't create programs that have runaway memory allocation without running into this problem and having to examine exactly what they are doing).
So this given there are several approaches you could take to either determine what amount of memory you need or to reduce the amount of memory you are using. One common mistake with garbage collected languages such as Java or C# is to keep around references to objects that you no longer are using, or allocating many objects when you could reuse them instead. As long as objects have a reference to them they will continue to use heap space as the garbage collector will not delete them.
In this case you can use a Java memory profiler to determine what methods in your program are allocating large number of objects and then determine if there is a way to make sure they are no longer referenced, or to not allocate them in the first place. One option which I have used in the past is "JMP" http://www.khelekore.org/jmp/.
If you determine that you are allocating these objects for a reason and you need to keep around references (depending on what you are doing this might be the case), you will just need to increase the max heap size when you start the program. However, once you do the memory profiling and understand how your objects are getting allocated you should have a better idea about how much memory you need.
In general if you can't guarantee that your program will run in some finite amount of memory (perhaps depending on input size) you will always run into this problem. Only after exhausting all of this will you need to look into caching objects out to disk etc. At this point you should have a very good reason to say "I need Xgb of memory" for something and you can't work around it by improving your algorithms or memory allocation patterns. Generally this will only usually be the case for algorithms operating on large datasets (like a database or some scientific analysis program) and then techniques like caching and memory mapped IO become useful.
Run Java with the command-line option -Xmx, which sets the maximum size of the heap.
See here for details.
You could specify per project how much heap space your project wants
Following is for Eclipse Helios/Juno/Kepler:
Right mouse click on
Run As - Run Configuration - Arguments - Vm Arguments,
then add this
-Xmx2048m
Increasing the heap size is not a "fix" it is a "plaster", 100% temporary. It will crash again in somewhere else. To avoid these issues, write high performance code.
Use local variables wherever possible.
Make sure you select the correct object (EX: Selection between String, StringBuffer and StringBuilder)
Use a good code system for your program(EX: Using static variables VS non static variables)
Other stuff which could work on your code.
Try to move with multy THREADING
Big caveat ---- at my office, we were finding that (on some windows machines) we could not allocate more than 512m for Java heap. This turned out to be due to the Kaspersky anti-virus product installed on some of those machines. After uninstalling that AV product, we found we could allocate at least 1.6gb, i.e, -Xmx1600m (m is mandatory other wise it will lead to another error "Too small initial heap") works.
No idea if this happens with other AV products but presumably this is happening because the AV program is reserving a small block of memory in every address space, thereby preventing a single really large allocation.
I would like to add recommendations from oracle trouble shooting article.
Exception in thread thread_name: java.lang.OutOfMemoryError: Java heap space
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 causes:
Simple configuration issue, where the specified heap size is insufficient for the application.
Application is unintentionally holding references to objects, and this prevents the objects from being garbage collected.
Excessive use of finalizers.
One other potential source of this error arises with 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
After garbage collection, the objects are queued for finalization, which occurs at a later time. finalizers are executed by a daemon thread that services the finalization queue. 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.
One scenario that can cause this situation is when an application creates high-priority threads that cause the finalization queue to increase at a rate that is faster than the rate at which the finalizer thread is servicing that queue.
VM arguments worked for me in eclipse. If you are using eclipse version 3.4, do the following
go to Run --> Run Configurations --> then select the project under maven build --> then select the tab "JRE" --> then enter -Xmx1024m.
Alternatively you could do Run --> Run Configurations --> select the "JRE" tab --> then enter -Xmx1024m
This should increase the memory heap for all the builds/projects. The above memory size is 1 GB. You can optimize the way you want.
Yes, with -Xmx you can configure more memory for your JVM.
To be sure that you don't leak or waste memory. Take a heap dump and use the Eclipse Memory Analyzer to analyze your memory consumption.
Follow below steps:
Open catalina.sh from tomcat/bin.
Change JAVA_OPTS to
JAVA_OPTS="-Djava.awt.headless=true -Dfile.encoding=UTF-8 -server -Xms1536m
-Xmx1536m -XX:NewSize=256m -XX:MaxNewSize=256m -XX:PermSize=256m
-XX:MaxPermSize=256m -XX:+DisableExplicitGC"
Restart your tomcat
By default for development JVM uses small size and small config for other performance related features. But for production you can tune e.g. (In addition it Application Server specific config can exist) -> (If there still isn't enough memory to satisfy the request and the heap has already reached the maximum size, an OutOfMemoryError will occur)
-Xms<size> set initial Java heap size
-Xmx<size> set maximum Java heap size
-Xss<size> set java thread stack size
-XX:ParallelGCThreads=8
-XX:+CMSClassUnloadingEnabled
-XX:InitiatingHeapOccupancyPercent=70
-XX:+UnlockDiagnosticVMOptions
-XX:+UseConcMarkSweepGC
-Xms512m
-Xmx8192m
-XX:MaxPermSize=256m (in java 8 optional)
For example: On linux Platform for production mode preferable settings.
After downloading and configuring server with this way http://www.ehowstuff.com/how-to-install-and-setup-apache-tomcat-8-on-centos-7-1-rhel-7/
1.create setenv.sh file on folder /opt/tomcat/bin/
touch /opt/tomcat/bin/setenv.sh
2.Open and write this params for setting preferable mode.
nano /opt/tomcat/bin/setenv.sh
export CATALINA_OPTS="$CATALINA_OPTS -XX:ParallelGCThreads=8"
export CATALINA_OPTS="$CATALINA_OPTS -XX:+CMSClassUnloadingEnabled"
export CATALINA_OPTS="$CATALINA_OPTS -XX:InitiatingHeapOccupancyPercent=70"
export CATALINA_OPTS="$CATALINA_OPTS -XX:+UnlockDiagnosticVMOptions"
export CATALINA_OPTS="$CATALINA_OPTS -XX:+UseConcMarkSweepGC"
export CATALINA_OPTS="$CATALINA_OPTS -Xms512m"
export CATALINA_OPTS="$CATALINA_OPTS -Xmx8192m"
export CATALINA_OPTS="$CATALINA_OPTS -XX:MaxMetaspaceSize=256M"
3.service tomcat restart
Note that the JVM uses more memory than just the heap. For example
Java methods, thread stacks and native handles are allocated in memory
separate from the heap, as well as JVM internal data structures.
I read somewhere else that you can try - catch java.lang.OutOfMemoryError and on the catch block, you can free all resources that you know might use a lot of memory, close connections and so forth, then do a System.gc() then re-try whatever you were going to do.
Another way is this although, i don't know whether this would work, but I am currently testing whether it will work on my application.
The Idea is to do Garbage collection by calling System.gc() which is known to increase free memory. You can keep checking this after a memory gobbling code executes.
//Mimimum acceptable free memory you think your app needs
long minRunningMemory = (1024*1024);
Runtime runtime = Runtime.getRuntime();
if(runtime.freeMemory()<minRunningMemory)
System.gc();
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 ran 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"
Reference Link
If you came here to search this issue from REACT NATIVE.
Then i guess you should do this
cd android/ && ./gradlew clean && cd ..
Add this line to your gradle.properties file
org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
It should work. You can change MaxPermSize accordingly to fix your heap problem
I have faced same problem from java heap size.
I have two solutions if you are using java 5(1.5).
just install jdk1.6 and go to the preferences of eclipse and set the jre path of jav1 1.6 as you have installed.
Check your VM argument and let it be whatever it is.
just add one line below of all the arguments present in VM arguments as
-Xms512m -Xmx512m -XX:MaxPermSize=...m(192m).
I think it will work...
If you need to monitor your memory usage at runtime, the java.lang.management package offers MBeans that can be used to monitor the memory pools in your VM (eg, eden space, tenured generation etc), and also garbage collection behaviour.
The free heap space reported by these MBeans will vary greatly depending on GC behaviour, particularly if your application generates a lot of objects which are later GC-ed. One possible approach is to monitor the free heap space after each full-GC, which you may be able to use to make a decision on freeing up memory by persisting objects.
Ultimately, your best bet is to limit your memory retention as far as possible whilst performance remains acceptable. As a previous comment noted, memory is always limited, but your app should have a strategy for dealing with memory exhaustion.
In android studio add/change this line at the end of gradle.properties (Global Properties):
...
org.gradle.jvmargs=-XX\:MaxHeapSize\=1024m -Xmx1024m
if it doesn't work you can retry with bigger than 1024 heap size.
add the below code inside android/gradle.properties:
org.gradle.jvmargs=-Xmx4096m -XX:MaxPermSize=4096m -XX:+HeapDumpOnOutOfMemoryError
org.gradle.daemon=true
org.gradle.parallel=true
org.gradle.configureondemand=true
Note that if you need this in a deployment situation, consider using Java WebStart (with an "ondisk" version, not the network one - possible in Java 6u10 and later) as it allows you to specify the various arguments to the JVM in a cross platform way.
Otherwise you will need an operating system specific launcher which sets the arguments you need.
In my case it solved by assigning more memory to Shared build process heap size in intellij settings.
Go to intellij settings > Compiler > Shared build process heap size
Regarding to netbeans, you could set max heap size to solve the problem.
Go to 'Run', then --> 'Set Project Configuration' --> 'Customise' --> 'run' of its popped up window --> 'VM Option' --> fill in '-Xms2048m -Xmx2048m'.
If you are using Android Studio just add these lines with gradle.properties file
org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
Android Studio
File -> Invalidate Caches and Restart solved it for me :)
If this issue is happening in Wildfly 8 and JDK1.8,then we need to specify MaxMetaSpace settings instead of PermGen settings.
For example we need to add below configuration in setenv.sh file of wildfly.
JAVA_OPTS="$JAVA_OPTS -XX:MaxMetaspaceSize=256M"
For more information, please check Wildfly Heap Issue
If you keep on allocating & keeping references to object, you will fill up any amount of memory you have.
One option is to do a transparent file close & open when they switch tabs (you only keep a pointer to the file, and when the user switches tab, you close & clean all the objects... it'll make the file change slower... but...), and maybe keep only 3 or 4 files on memory.
Other thing you should do is, when the user opens a file, load it, and intercept any OutOfMemoryError, then (as it is not possible to open the file) close that file, clean its objects and warn the user that he should close unused files.
Your idea of dynamically extending virtual memory doesn't solve the issue, for the machine is limited on resources, so you should be carefull & handle memory issues (or at least, be carefull with them).
A couple of hints i've seen with memory leaks is:
--> Keep on mind that if you put something into a collection and afterwards forget about it, you still have a strong reference to it, so nullify the collection, clean it or do something with it... if not you will find a memory leak difficult to find.
--> Maybe, using collections with weak references (weakhashmap...) can help with memory issues, but you must be carefull with it, for you might find that the object you look for has been collected.
--> Another idea i've found is to develope a persistent collection that stored on database objects least used and transparently loaded. This would probably be the best approach...
Java OOM Heap space issue can also arise when your DB connection pool got full.
I faced this issue because of my Hikari Connection pool (when upgraded to Spring boot 2.4.*) was full and not able to provide connections anymore (all active connections are still pending to fetch results from database).
Issue is some of our native queries in JPA Repositories contain ORDER BY ?#{#pageable} which takes a very long time to get results when upgraded.
Removed ORDER BY ?#{#pageable} from all the native queries in JPA repositories and OOM heap space issue along with connection pool issue got resolved.
If this error occurs right after execution of your junit tests, then you should execute Build -> Rebuild Project.
If this error comes up during APK generation in react-native, cd into the android folder in your project and do:
./gradlew clean
then
./gradlew assembleRelease
If error persists, then, restart your machine.
In Intellij, it worked for me just by giving the "Build Project"
If everything else fails, in addition to increasing the max heap size try also increasing the swap size. For Linux, as of now, relevant instructions can be found in https://linuxize.com/post/create-a-linux-swap-file/.
This can help if you're e.g. compiling something big in an embedded platform.

Jenkins java.lang.OutOfMemoryError: GC overhead limit exceeded

I am currently working on creating a performance framework using jenkins and execute the performance test from Jenkins. I am using https://github.com/jmeter-maven-plugin/jmeter-maven-plugin this plugin. The sanity test with single user in this performance framework worked well and went ahead with an actual performance test of 200 users and within 2 mins received the error
java.lang.OutOfMemoryError: GC overhead limit exceeded
I tried the following in jenkins.xml
<arguments>-Xrs -Xmx2048m -XX:MaxPermSize=512m -Dhudson.lifecycle=hudson.lifecycle.WindowsServiceLifecycle -jar "%BASE%\jenkins.war" --httpPort=8080 --prefix=/jenkins --webroot="%BASE%\war"</arguments>
but it didn't work and also noted that whenever I increased the memory the jenkins service stops and had to reduce the memory to 1Gb and then the service restarts.
Had increased the memory for jmeter and java as well but no help.
In the .jmx file view results tree and every other listener is disabled but still the issue persists.
Since I am doing a POC jenkins is hosted in my laptop and high level specs as follows
System Model : Latitude E7270 Processor : Intel(R) Core(TM) i5-6300U CPU # 2.40GHZ(4CPU's), ~2.5GHZ Memory : 8192MB RAM
Any help please ?
The error about GC overhead implies that Jenkins is thrashing in Garbage Collection. This means it's probably spending more time doing Garbage Collection than doing useful work.
This situation normally comes about when the heap is too small for the application. With modern multi generational heap layouts it's difficult to say what exactly needs changing.
I would suggest you enable Verbose GC with the following options "-verbose:gc -XX:+PrintGCDetails -XX:+PrintGCTimeStamps"
Then follow the advice here: http://www.oracle.com/technetwork/articles/javase/gcportal-136937.html
Few points to note
You are using the integrated maven goal to run your jmeter tests. This will use Jenkins as the container to launch your jmeter tests thereby not only impacting your work but also other users of jenkins
It is better to defer the execution to a different client machine like a dedicated jmeter machine which uses its own JVM with parameters to launch your tests (OR) use the one that you provide
In summary,
1. Move the test execution out of jenkins
2. Provide the output of the report as an input to your performance plug-in [ this can also crash since it will need more JVM memory when you process endurance test results like an 8 hour result file]
This way, your tests will have better chance of scaling. Also, you haven't mentioned what type of scripting engine that you are using. AS per Jmeter documentation, JSR223 with groovy has a memory leak. Please refer
http://jmeter.apache.org/usermanual/component_reference.html#JSR223_Sampler
Try adding -Dgroovy.use.classvalue=true to see if that helps (provided you are using groovy). If you are using Java 8, there is a high chance that it is creating unique class for all your scripts in jmeter and it is increasing the meta space which is outside your JVM. In that case, restrict the meta space and use class unloading and a 64 bit JVM like
-d64 -XX:+CMSClassUnloadingEnabled.
Also, what is your new generation size. -XX:NewSize=1024m -XX:MaxNewSize=1024m ? Please note jmeter loads all the files permanently and it will go directly to the old generation thereby shrinking any available space for new generation.

Process Memory Vs Heap -- JVM

We have a web application deployed on a tomcat server. There are certain scheduled jobs which we run, after which the heap memory peaks up and settles down, everything seems fine.
However the system admin is complaining that memory usage ('top' on Linux ) keeps increasing the more the scheduled jobs are.
Whats the co-relation between heap memory and memory of the CPU? Can it be controlled by any JVM settings? I used JConsole to monitor the system.
I forced the garbage collection through JConsole and the heap usage came down, however the memory usage on Linux remained high and it never decreased.
Any ideas or suggestions would of great help?
The memory allocated by the JVM process is not the same as the heap size. The used heap size could go down without an actual reduction in the space allocated by the JVM. The JVM has to receive a trigger indicating it should shrink the heap size. As #Xepoch mentions, this is controlled by -XX:MaxHeapFreeRatio.
However the system admin is complaining that memory usage ('top' on Linux ) keeps increasing the more the scheduled jobs are [run].
That's because you very likely have some sort of memory leak. System admins tend to complain when they see processes slowly chew up more and more space.
Any ideas or suggestions would of great help?
Have you looked at the number of threads? Is you application creating its own threads and sending them off to deadlock and wait idly forever?
Are you integrating with any third party APIs which may be using JNI?
What is likely being observed is the virtual size and not the resident set size of the Java process(es)? If you have a goal for a small footprint, you may want to not include -Xms or any minimum size on the JVM heap arguments and adjust the 70% -XX:MaxHeapFreeRatio= to a smaller number to allow for more aggressive heap shrinkage.
In the meantime, provide more detail as to what was observed with the comment the Linux memory never decreased? What metric?
You can use -Xmx and -Xms settings to adjust the size of the heap. With tomcat you can set an environment variable before starting:
export JAVA_OPTS=”-Xms256m -Xmx512m”
This initially creates a heap of 256MB, with a max size of 512MB.
Some more details:
http://confluence.atlassian.com/display/CONF25/Fix+'Out+of+Memory'+errors+by+increasing+available+memory

ActiveMQ OutOfMemory Can't create more threads

I'm simulating a overload of a server and I'm getting this error:
java.lang.OutOfMemoryError: unable to create new native thread
I've read in this page http://activemq.apache.org/javalangoutofmemory.html, that I can increase the memory size. But how do I do that? Which file I need to modify,? I tried to pass the arguments by the bin/activemq script but no luck.
Your case corresponds to massive number of threads.
There are 3 ways to solve it:
reduce number of threads (i.e., -Dorg.apache.activemq.UseDedicatedTaskRunner=false in the document)
reduce per-thread stack size by -Xss option (default values: 320 KiB for 32-bit Java on Win/Linux, 1024 KiB for 64-bit Java on Win/Linux, see doc)
reduce (not extend) heap size -Xmx option to make a room for per-thread stacks (512 MiB by default in ActiveMQ script)
Note: If stack or heap is too small, it must cause another OutOfMemoryError.
You can specify them using ACTIVEMQ_OPTS shell variable (in UNIX).
For example, run ActiveMQ as
ACTIVEMQ_OPTS=-Xss160k bin/activemq
Check here
Specify the -Xmx argument to the VM that is running the ActiveMQ - Tomcat, for example.
You could assign the Java virtual machine more memory using the -Xmx command argument.
Eg. java -Xmx512M MyClass
We were running into this issue on a Linux (RedHat Enterprise 5) system and discovered that on this build the nprocs ulimit in /etc/security/limits.conf actually controls the number of threads a user can spawn.
You can view this limit using the ulimit -a command.
Out of the box this was set to a soft limit of 100 and a hard limit of 150, which is woefully short of the number of threads necessary to run a modern App Server.
We removed this limit altogether and it solved this issue for us.
This doesn't look like you are running out of heap space, so don't increase that (the -Xmx option). Instead, your application is running out of process memory and decreasing the heap space will free up process memory for native use. The question is, why you are using so much process memory? If you don't use JNI, you probably have created too many threads, and habe's post has explained how to do fix that.

Categories