I ran this command which I found in this blog.
docker run -m 1GB openjdk:10 java \
-XX:+UseContainerSupport \
-XX:MinRAMPercentage=50 \
-XX:MaxRAMPercentage=80 \
-XshowSettings:vm \
-version
My output is this.
VM settings:
Max. Heap Size (Estimated): 3.86G
Using VM: OpenJDK 64-Bit Server VM
openjdk version "10.0.2" 2018-07-17
OpenJDK Runtime Environment (build 10.0.2+13-Debian-2)
OpenJDK 64-Bit Server VM (build 10.0.2+13-Debian-2, mixed mode)
I am little bit confused now is that , when I limit the memory to 1G, why does Java see 3.86G or What needs to be done to make java see container memory limits ?
Note: I am on MAC. docker creates container inside the VM. So not sure if it matters.
When using Java in containers, one needs to be mindful of to what degree the JVM is aware of the resource limits set for the container it runs in. With Java version 10 (released in 2018) the JVM was first enabled to figure out whether it is running in a container, and if yes, how much memory was allocated to the container. Back then, CGroups V1 was used by the Linux Kernel to curtail the memory available to containers.
In the mean time, CGroups V2 (conceived in 2016) is gaining traction and is increasingly becoming the default for new Linux releases (e.g. Ubuntu and Flatcar Linux made it default in 2021). This means, once again a Java update is required to support CGroups V2 for correct handling of JVM resource limits and Heap configuration, which for OpenJDK came with Java version 15.
Related
I switched to the Azul JVM in order to use a native ARM JVM and Solr was no longer able to start up. I started seeing a new error in the log:
The stack size specified is too small, Specify at least 384k
If I switch back to the Oracle jvm I do not get this error.
Requirements for stack size appears to be different between ARM and x86 JVMs.
The relevant lines setting the default in bin/solr is:
# Pick default for Java thread stack size, and then add to SOLR_OPTS
if [ -z ${SOLR_JAVA_STACK_SIZE+x} ]; then
SOLR_JAVA_STACK_SIZE='-Xss256k'
fi
SOLR_OPTS+=($SOLR_JAVA_STACK_SIZE)
The default is too small for the ARM JVM to start up. To increase the stack size add the following line to bin/solr.in.cmd
SOLR_JAVA_STACK_SIZE='-Xss512k'
I faced the same error when trying to start Solr for my Rails app.
After a lot of digging, I fixed it by adding the following line to my .zshrc file.
export _JAVA_OPTIONS='-Xss512k'
My use case:
macOS Monterey (M1 2020)
openjdk version "1.8.0_332"
OpenJDK Runtime Environment (Zulu 8.62.0.19-CA-macos-aarch64) (build 1.8.0_332-b09)
OpenJDK 64-Bit Server VM (Zulu 8.62.0.19-CA-macos-aarch64) (build 25.332-b09, mixed mode)
I am trying to profile a remote JVM with VisualVM 1.4. I am running macOS High Sierra 10.13.6 locally, with the following OpenJDK version:
java -version
openjdk version "1.8.0_181"
OpenJDK Runtime Environment (AdoptOpenJDK)(build 1.8.0_181-b13)
OpenJDK 64-Bit Server VM (AdoptOpenJDK)(build 25.181-b13, mixed mode)
The server runs Debian Stretch with the following OpenJDK:
java -version
openjdk version "1.8.0_181"
OpenJDK Runtime Environment (build 1.8.0_181-8u181-b13-2~deb9u1-b13)
OpenJDK 64-Bit Server VM (build 25.181-b13, mixed mode)
When I monitor a JVM process locally, I see all these tabs and the profiling works just fine.
However, if I do that remotely, I see something like this:
Note the CPU window that says "Not supported for this JVM" and the reduced tabs, not including "Profiler". However, as you can see, I do see some data.
I am connecting via jstatd. On the server, following this article, I am running
jstatd -J-Djava.security.policy=/home/brandwatch/jstatd.all.policy -J-Djava.rmi.server.hostname=10.2.156.160 -Djava.rmi.server.logCalltrue
Answers like this indicate that this might be due to different JVM versions, however, mine appear to be the same, despite one of them running on MacOS and one of them on Debian.
Missing CPU usage information has nothing to do with with different JDK versions. You don't see CPU usage data because jvmstat (exported via jstatd) does not provide such information. If you want to see CPU usage, you need to use JMX connection. JMX will also allow you to do CPU and Memory sampling. Profiling is supported for local applications only.
Because, as Tomas Hurka's answer correctly indicates, remote profiling does not work with VisualVM, I have used a little hack to still make it work: I have installed VisualVM on the remote server and accessed it via X-forwarding. That way, VisualVM can access the process locally an thus profile it.
ssh into the server with the -X flag
ssh -C -X <user>#<host>
download [VisualVM 1.4][8]
wget https://github.com/visualvm/visualvm.src/releases/download/1.4/visualvm_14.zip
unzip the archive
unzip visualvm_14.zip
run VisualVM
./visualvm_14/bin/visualvm
After a few seconds you should see a VisualVM window pop up. It's not very fast (just because x-forwarding is not), but for my use case it was alright.
Another way of achieving this might be using VNC, but I haven't tried that. The downside would be that you have to install all the desktop packages, which one might not want on a server.
How do I configure my JVM for Spark on Yarn?
I want to increase the maxiumum and minimum heap space using -Xmx and -Xms etc. However, I do not know how to use the commands or which program running java to apply it to because spark looks like it has multiple programs running on java. See the image for more information.
First, I ssh to my cluster. Second, I start an Ipython notebook. Third, I start spark.
Starting Spark Code
ssh -i ~/.ssh/huddle-hadoop hadoop#ec2-54-83-79-162.compute-1.amazonaws.com
export IPYTHON_OPTS="notebook"
~/spark/bin/pyspark --master yarn-client --num-executors 200 --executor-memory 4g
Details
java version "1.7.0_71"
Java(TM) SE Runtime Environment (build 1.7.0_71-b14)
Java HotSpot(TM) 64-Bit Server VM (build 24.71-b01, mixed mode)
I'm running a java web server as an internal component of another project, and unfortunately java insists on running in server mode (i.e. fast, and huge memory footprint), even when I pass the -client switch.
This is a problem because java takes up so much memory that my whole project is killed by the server.
I'm running java with the command:
java -client -classpath /home/marcintustin/webapps/django/oneclickcosvirt/oneclickcos/java:/home/marcintustin/webapps/django/oneclickcosvirt/oneclickcos/java/commons-fileupload-1.2.2.jar:/home/marcintustin/webapps/django/oneclickcosvirt/oneclickcos/java/fop-20120125.jar:/home/marcintustin/webapps/django/oneclickcosvirt/oneclickcos/java/xmlgraphics-commons-1.5svn.jar:/home/marcintustin/webapps/django/oneclickcosvirt/oneclickcos/java/batik-all.jar:/home/marcintustin/webapps/django/oneclickcosvirt/oneclickcos/java/docx4j-nightly-20120105.jar:/home/marcintustin/webapps/django/oneclickcosvirt/oneclickcos/java/spark-0.9.9.3-SNAPSHOT.jar:/home/marcintustin/webapps/django/oneclickcosvirt/oneclickcos/java/slf4j-log4j12-1.6.1.jar:/home/marcintustin/webapps/django/oneclickcosvirt/oneclickcos/java/slf4j-api-1.6.1.jar:/home/marcintustin/webapps/django/oneclickcosvirt/oneclickcos/java/jetty-webapp-7.3.0.v20110203.jar:/home/marcintustin/webapps/django/oneclickcosvirt/oneclickcos/java/servlet-api-3.0.pre4.jar:/home/marcintustin/webapps/django/oneclickcosvirt/oneclickcos/java/antlr-2.7.7.jar:/home/marcintustin/webapps/django/oneclickcosvirt/oneclickcos/java/commons-codec-1.6.jar:/home/marcintustin/webapps/django/oneclickcosvirt/oneclickcos/java/docx4j-2.7.1.jar:/home/marcintustin/webapps/django/oneclickcosvirt/oneclickcos/java/poi-scratchpad-3.8-beta4.jar:/home/marcintustin/webapps/django/oneclickcosvirt/oneclickcos/java/xalan-2.7.1.jar:/home/marcintustin/webapps/django/oneclickcosvirt/oneclickcos/java/antlr-runtime-3.3.jar:/home/marcintustin/webapps/django/oneclickcosvirt/oneclickcos/java/commons-io-2.1.jar:/home/marcintustin/webapps/django/oneclickcosvirt/oneclickcos/java/serializer-2.7.1.jar:/home/marcintustin/webapps/django/oneclickcosvirt/oneclickcos/java/xml-apis-1.3.04.jar:/home/marcintustin/webapps/django/oneclickcosvirt/oneclickcos/java/avalon-framework-api-4.3.1.jar:/home/marcintustin/webapps/django/oneclickcosvirt/oneclickcos/java/commons-lang-2.4.jar:/home/marcintustin/webapps/django/oneclickcosvirt/oneclickcos/java/log4j-1.2.15.jar:/home/marcintustin/webapps/django/oneclickcosvirt/oneclickcos/java/stringtemplate-3.2.1.jar:/home/marcintustin/webapps/django/oneclickcosvirt/oneclickcos/java/avalon-framework-impl-4.3.1.jar:/home/marcintustin/webapps/django/oneclickcosvirt/oneclickcos/java/commons-logging-1.1.1.jar:/home/marcintustin/webapps/django/oneclickcosvirt/oneclickcos/java/poi-3.8-beta4.jar:/home/marcintustin/webapps/django/oneclickcosvirt/oneclickcos/java/wmf2svg-0.9.0.jar: Transcoder
java -version reports:
java version "1.7.0"
Java(TM) SE Runtime Environment (build 1.7.0-b147)
Java HotSpot(TM) 64-Bit Server VM (build 21.0-b17, mixed mode)
As I'm on a shared host, I can't install 32-bit compatibility libraries, so I can't use the 32-bit JRE. This turns out to be a problem because as confirmed by #birryree in the comments (thanks!), 64-bit JRE always runs in server mode.
Is there a way to force java to run in normal client mode?
Based on comments received (and testing), it seems that the 64bit JVM ALWAYS runs in server mode, which means that it is VERY profligate with memory.
The work-arounds are:
Get the 32bit JVM (and appropriate compatibility libraries if on Linux); or
Use the -X options to limit memory to a certain maximum.
From my experience with Windows 7 (64-bit) and Java, a 32-bit JRE uses less memory and runs significantly faster than a 64-bit JRE (provided you don't need or benefit from having a lot of memory). I imagine the same thing is true for Mac OSX (and other platforms) as well.
I am currently running OSX Lion (v10.7), and I have installed the standard Java app. Under Java Preferences, I see "Java SE 6" from "Apple Inc." for both CPU-types "32-bit" and "64-bit" version "1.6.0_26-b03-383". I have changed the preferred order to put the 32-bit version on top of the 64-bit version, hoping that this would make the 32-bit version default.
But "java -version" still says:
java version "1.6.0_26"
Java(TM) SE Runtime Environment (build 1.6.0_26-b03-383-11A511c)
Java HotSpot(TM) 64-Bit Server VM (build 20.1-b02-383, mixed mode)
Is it possible to use the 32-bit version by default? And how?
Also, does anyone have experiences / comparative measurements regarding speed and memory efficiency between the 32/64-bit versions?
I found out now, that the 32-bit JVM can be explicitly launched using the -d32 switch.
On my machine, "java -version -d32" says:
java version "1.6.0_26"
Java(TM) SE Runtime Environment (build 1.6.0_26-b03-383-11A511c)
Java HotSpot(TM) Client VM (build 20.1-b02-383, mixed mode)
and although it doesn't say so, it is a 32-bit JVM.
The latest versions of Java 64-bit have -XX:+UseCompressedOops on by default (if your heap is less than 32 GB). This means 32-bit references are used in any case. The objects are still slightly bigger (4 bytes more overhead)
This article compares 32-bit, 64-bit with UseCompressedOops Java: How much memory do different arrays and collections consume
In terms of performance, I have found it to be 5-10% depending on what you are doing. If you are using a lot of long values it will be faster to use 64-bit.
Go into the "Java Preferences" App and drag java 32 bit to the top of the list.
Try the below steps:
Open terminal and go to /System/Library/Frameworks/JavaVM.framework/Versions/
Type ls -l to list all available Java versions
Enter sudo ln -fhsv CurrentJDK
Reference: Changing Java Version
in /System/Library/Frameworks/JavaVM.framework/Versions
I found version 1.6 installed and changed the path for java,javac to point to
/System/Library/Frameworks/JavaVM.framework/Versions/1.6/home using environment
alias rather than the default link found in /usr/bin/