Java 8 Memory allocation - java

Let's assume that I have JDK/JRE 8 also I've added JAVA_OPTS= -Xmx8G -Xms1G.
I've stated without any other params (java -jar 1.jar; java -jar 2.jar) 2 simple jars. So now I have two java process.
1) Do they executed in one JVM (as two java process) or each process will be executed in separated JVM?
2) -Xmx8G -Xms1G heap size will be applied to separately each of two executed jars or this heap size will be something common for two executed jars?
3) What will be with memory allocation if start one jar ( java -jar 1.jar)
and another with java -jar 2.jar Xmx12G?
P.S. Would we nice if you have any good links.
P.S.S Don't Ask what I'm smoking :)

The best way is to analyze JVM instances in your system. Just open JMC(Java Mission Control). Whenever you execute any application it will show as an individual jvm there. ex : if you run jar1 and jar2 the JMC will show three JVMs- jar1, jar2 ,jmc. Then, you can use use MBean Browser there to analyze your all jvm.
Hope it helps.

Related

Increasing the JVM heap memory using Xmx doesn't work

I'm developping a javafx application which has much ui interfaces, and while opening many windows, the jvm start consumming much memory (going up tp 350mb).
When it arrives to 360mb, the programs starts lagging and end up by being crashed (nothing works, screen blocks ...) and the console show a OutOfMemoryException with Java Heap Space error
I've 6gb of memory in my computer, and tried to start the .jar file using -Xmx param, but still the operating system doesn't allow the jvm to consume more memory.
Is there anything else i should specify so that the jvm may be able to get as much memory as it needs ?
You might want to ensure that you're using:
java -Xmx1024m -jar YourApplication.jar
and not:
java -jar YourApplication.jar -Xmx1024m
Anything after the .jar is considered as argument passed to your executable Jar.

JMeter Dashboard Generation Java Heap Space

I've been able to create dashboards for small amounts of log data (3mb) with JMeter. However, when trying to create dashboards with large amounts of data (35mb), jmeter will throw a java.lang.OutOfMemoryError: Java Heap Space.
So far I've tried to create an environment variable called JVM_ARGS=-Xms1024m -Xmx10240m but I still do not have enough space.
Is there anything else I can try to create these dashboards? Or is there a way to reduce the number of entries that get written to the log file?
Thank you!
There are 2 possibilities :
Option 1 : your JVM options are not taken into account. Show the first lines or all content of jmeter.log
Option 2 : you have added some dynamic parameter to your http requests that has created a lot of different (name) SampleResult
Edit 8 october 2018:
Root cause was point Option 2
Make sure you've really created the environment variable and it has the anticipated value, double check this by running the following command in the terminal window where you will be launching JMeter from:
echo %JVM_ARGS% for Windows
echo $JVM_ARGS for Linux/Unix/MacOS
You should see your increased JVM heap settings
Make sure to use either jmeter.bat for Windows or jmeter.sh for other operating systems wrapper script
Make sure to use 64-bit version of JRE as 32-bit will not be able to allocate more than 3G heap
Make sure you can execute java command with your 10G heap
java -Xms1024m -Xmx10240m -version
you should see your Java version
Try running ApacheJMeter.jar executable directly:
java -Xms1024m -Xmx10240m -jar ApacheJMeter.jar -g result.jtl -o destination_folder
If nothing helps be aware that you can generate tables/charts using JMeterPluginsCMD Command Line Tool (it is not a part of standard JMeter installation, can be installed using JMeter Plugins Manager)

How to prevent Java from exceeding the container memory limits?

I'm running a Java program inside a Docker container that has a hard memory limit of 4GB. I've set the max heap to 3GB but still the Java program exceeds the limit and gets killed (OOMKilled).
My question is: How can I configure Java to respect the set container limit and throw an OutOfMemoryException instead of trying to allocate beyond the limit and get its ass kicked by the host kernel?
Update: I'm an experienced Java developer and have a fair understanding of the JVM. I know how to set the max heap, but I wonder if anyone knows of a way to set a limit to the total memory that the JVM process claims from the OS.
When a Java application is executed inside a container, the JVM ergonomics (which is responsible for dynamically assign resources based on the host's capabilities) does not know it is running inside a container and it calculates the number of resources to be used by the Java app based on the host that is executing your container. Given that, it does not matter if you set limits to your container, the JVM will take your host's resources as the base for doing that calculation.
From JDK 8u131+ and JDK 9, there’s an experimental VM option that allows the JVM ergonomics to read the memory values from CGgroups. To enable it you must pass the following flags to the JVM:
-XX:+UnlockExperimentalVMOptions and -XX:+UseCGroupMemoryLimitForHeap
If you enable these flags, the JVM will be aware that is running inside a container and will make the JVM ergonomics to calculate the app's resources based on the container limits and not the host's capabilities.
Enabling the flags:
$ java -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap -jar app.jar
You can dynamically pass the JVM options to your container with ENV variables.
Example:
The command to run your app would like something like:
$ java ${JAVA_OPTIONS} -jar app.jar
And the docker run command needs to pass the ENV variable like this:
$ docker run -e JAVA_OPTIONS="-XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap" myJavaImage
Hope this helps!
In addition to Fabian Rivera's answer I've found that Java 10 has good support for running in containers without any custom startup parameters. By default it uses 25% of the containers memory as heap, which might be a bit low for some users. You can change this with the following parameter:
-XX:MaxRAMPercentage=50
To play around with Java 10 run the following docker command:
docker run -it --rm -m1g --entrypoint bash openjdk:10-jdk
It will give you a bash environment where you can run executables from the JDK. For instance, to run a small piece of script you can use jrunscript like this:
jrunscript -e "print(Packages.java.lang.Runtime.getRuntime().maxMemory()/(1<<20) + 'M')"
This will show you the size of the heap in MB. To change the percentage of total container memory that is used for the heap add the MaxRAMPercentage parameter like this:
jrunscript -J-XX:MaxRAMPercentage=50 -e "print(Packages.java.lang.Runtime.getRuntime().maxMemory()/(1<<20) + 'M')"
Now you can play around with the sizing of the container and the max percentage of heap.

Find .jar file of other java process

Basically, given a jvm (the process named Java (TM) Platform SE binary) process id, can i find the underlying .jar file that the jvm is running? Can I do this from other languages (non-java)? I know that the jps tool in the JDK can list the e.g. the starting arguments for the jvm process, but it does not list down the .jar file path, most times it just lists down the package name.
given a jvm process id, can i find the underlying .jar file that the
jvm is running?
Yes. Use jcmd utility:
jcmd <PID> VM.command_line
Can I do this from other languages?
Yes. See jattach for the C implementation.

Maven and JVM relation

Though not a direct programming question, it is related to Maven and JVM
While I was going thru this link - http://maven.apache.org/archives/maven-1.x/reference/command-line.html
Update of links: https://wiki.openstack.org/wiki/Documentation/Troubleshooting
https://maven.apache.org/docs/3.0/release-notes.html
it says about MAVEN_OPTS
"Specify additional options using the MAVEN_OPTS environment variable. It is for passing parameters to the Java VM when running Maven. For example, to increase the amount of memory to 1024 Meg for the entire run of Maven, use:
MAVEN_OPTS=-Xmx1024m "
Questions:
How Maven is able to set the JVM properties?
Why does Maven need JVM? It just build the war and JVM is needed only when u deploy the WAR to appserver.right?
Does Maven starts the JVM and stop it after use? IF it stops it after use, what's the point in setting more heap size?
My understanding after research:
(1) How/Why Maven is able to set the JVM properties?
Maven will be able to set the JVM properties using MAVEN_OPTS.
It is to pass the parameter to JVM for that run of Maven
(2) Why does Maven need JVM? Maven is just a build tool..
Maven has to build the WAR file, right? To build the WAR file, you need to compile the code,
and sometimes run the test cases. To compile the code, you need JVM. To run test cases you need JVM.
Don't know where else we need JVM when we do a mvn clean deploy.
[eg of javac passing JVM parameters otherwise: javac -d build/classes -classpath ... -J-Xms256m -J-Xmx1024m java-source-files]
(3) Does Maven starts the JVM and stop it after use? IF it stops it after use, what's the point in setting more heap size?
Yes , Maven starts the JVM and stop after its use. JVM is needed during its run. like if maven build needs lot of memory [like if you do XML processing] then
setting the heap memory using MAVEN_OPTS will be helpful.
Please clarify on my understanding especially on the second question
mvn is a shell script/batch file, and it uses MAVEN_OPTS to do what you'd expect.
Maven is Java. Maven tasks are written in Java.
...? Maven does a lot, and some of those things use memory. It's just a Java program. When it ends the JVM that was running it also ends.
To further clarify point 1, this is what happens at the end of the script:
exec "$JAVACMD" \
$MAVEN_OPTS \
-classpath "${M2_HOME}"/boot/plexus-classworlds-*.jar \
"-Dclassworlds.conf=${M2_HOME}/bin/m2.conf" \
"-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
${CLASSWORLDS_LAUNCHER} "$#"
Note: why read Maven 1 docs?
Maven is a program written in Java. This program is used to compile files, copy files, make jar files, and a whole lot of other tasks. As any Java program it needs a JVM to run. And as any Java program it uses memory. And as any Java program using memory, it can cause ot of memory errors if you don't start the JVM with enough memory.
mvn is able to set JVM properties because it's a simple shell script that starts a Java program: Maven.
And yes, once mvn exits, the JVM it started to run all the tasks it needs to run exits too.

Categories