[Building Sakai] On JAVA_OPTS

Warwick Chapman warwickchapman at gmail.com
Fri Sep 26 00:30:03 PDT 2014


On the JAVA_OPTS with specific reference to our documentation, I make the
following following submission:

Having been burnt by using the recommended JAVA_OPTS in the doumentation -
which are insufficient for production - I have paid them some attention.
In the end my approach was to go minimal both for the sake of clarity and
because I think the JVM is better at managing GC than I am.

I suggest we put the minimum recommended JAVA_OPTS on the installer and
link to a wiki page with more options for debugging etc.

Currently the recommended is:

export JAVA_OPTS='-server -Xms512m -Xmx1024m -XX:PermSize=128m
-XX:MaxPermSize=512m -XX:NewSize=192m -XX:MaxNewSize=384m
-Djava.awt.headless=true -Dhttp.agent=Sakai
-Dorg.apache.jasper.compiler.Parser.STRICT_QUOTE_ESCAPING=false
-Dsun.lang.ClassLoader.allowArraySyntax=true'


However, I suggest for Java 7:

export JAVA_OPTS='-d64 -Xmx1024m -XX:MaxPermSize=512m
-Djava.awt.headless=true -Dhttp.agent=Sakai
-Djava.util.Arrays.useLegacyMergeSort=true'


or perhaps in setenv.sh better structured as:
SERVER="-d64"
MAXHEAP="-Xmx4g"
MAXPERMGEN="-XX:MaxPermSize=512m"
HEADLESS="-Djava.awt.headless=true"
BUGFIX="-Dhttp.agent=Sakai -Djava.util.Arrays.useLegacyMergeSort=true"
export JAVA_OPTS="$SERVER $MAXHEAP $MAXPERMGEN $HEADLESS $BUGFIX"

As an explanation for the above approach, setting -Xms would not seem
necessary from everything I have read, and indeed the only seemingly
authoritative stuff I've read about -Xms suggests setting it to match Xmx
in production.  However, the defaults for Xms are reasonable and the heap
will grow as required so I do not believe this is necessary.

I see NewSize is specified but I can see no Sakai specific discussion or
documentation indicating why this is not better left to the JVM to
determine.  I have not used these in production nor do many other
deployments documented in PROD.

Since Java 5, the Server VM is automatically used on server hardware and
64-bit architectures so:
-d64 runs the application in a 64-bit environment. By default, the
application is run in a 32-bit environment.
-Xmx sets the maximum memory allocated to the JVM heap. Default is 1/4 of
system memory (eg. 1536M for 6144 system memory) *
-XX:MaxPermSize set the maximum amount of memory that can be used for
PermGen **
-Djava.awt.headless=true prevents graphics rendering code from assuming
that a graphics console exists

-Dhttp.agent=Sakai (Fix for https://jira.sakaiproject.org/browse/SAK-18044)
-Djava.util.Arrays.useLegacyMergeSort=true (Fix for
https://jira.sakaiproject.org/browse/KNL-1083?src=confmacro)

*
http://docs.oracle.com/javase/7/docs/technotes/guides/vm/gc-ergonomics.html
**
https://blogs.oracle.com/jonthecollector/entry/presenting_the_permanent_generation

*WIKI PAGE FOCUSING ON JVM TUNING*

Then perhaps we can have a wiki page (I am sure I remember one) which
includes this information:

The official garbage collection tuning strategy from Oracle is (since Java
5 and still accurate for Java 8):
Do not choose a maximum value for the heap unless you know that you need a
heap greater than the default maximum heap size. Choose a throughput goal
that is sufficient for your application.

The heap will grow or shrink to a size that will support the chosen
throughput goal. A change in the application's behavior can cause the heap
to grow or shrink. For example, if the application starts allocating at a
higher rate, the heap will grow to maintain the same throughput.

If the heap grows to its maximum size and the throughput goal is not being
met, the maximum heap size is too small for the throughput goal. Set the
maximum heap size to a value that is close to the total physical memory on
the platform but which does not cause swapping of the application. Execute
the application again. If the throughput goal is still not met, then the
goal for the application time is too high for the available memory on the
platform.

If the throughput goal can be met, but there are pauses that are too long,
then select a maximum pause time goal. Choosing a maximum pause time goal
may mean that your throughput goal will not be met, so choose values that
are an acceptable compromise for the application.

It is typical that the size of the heap will oscillate as the garbage
collector tries to satisfy competing goals. This is true even if the
application has reached a steady state. The pressure to achieve a
throughput goal (which may require a larger heap) competes with the goals
for a maximum pause time and a minimum footprint (which both may require a
small heap).

You can check your Java JVM options with the following command:
java -XX:+PrintFlagsFinal -version

In the output, if a default value was already modified then in the output
you will find a := instead of = as you can see in the following example:
uintx MaxHeapSize                              := 4148166656      {product}

More information on the various JVM options is here:
http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html

1. Java Heap Size
Place to store objects created by your Java application, this is where
Garbage Collection takes place, the memory used by your Java application.
For a heavy Java process, insufficient Heap size will cause the popular
java.lang.OutOfMemoryError: Java heap space.
-Xms<size> - Set initial Java heap size (Should not be necessary as default
meets Sakai requirements)
-Xmx<size> - Set maximum Java heap size

2. Perm Gen Size
Place to store your loaded class definition and metadata. If a large
code-base project is loaded, the insufficient Perm Gen size will cause the
popular Java.Lang.OutOfMemoryError: PermGen.
-XX:PermSize<size> - Set initial PermGen Size.
-XX:MaxPermSize<size> - Set the maximum PermGen Size

Read more on Heap Size and Garbage collection here:
http://docs.oracle.com/javase/7/docs/technotes/guides/vm/gc-ergonomics.html
http://docs.oracle.com/javase/8/docs/technotes/guides/vm/gctuning/ergonomics.html
http://www.oracle.com/technetwork/java/gc-tuning-5-138395.html (See "Total
Heap" and "Heap Size")
http://www.mkyong.com/java/find-out-your-java-heap-memory-size

Glossary:
- heap : The heap is the run-time data area from which memory for all class
instances and arrays is allocated.
- garbage collector : an automatic storage management system which reclaims
unused heap storage
- PermGen : The permanent generation is the area of the heap where class
and method objects are stored. If an application loads a very large number
of classes, then the size of the permanent generation might need to be
increased using the -XX:MaxPermSize option.

-- Warwick Bruce Chapman | +27 83 7797 094 | http://warwickchapman.com
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://collab.sakaiproject.org/pipermail/sakai-dev/attachments/20140926/be6ed8e4/attachment.html 


More information about the sakai-dev mailing list