Skip to content

Instantly share code, notes, and snippets.

@dekobon
Last active September 26, 2018 17:20
Show Gist options
  • Star 9 You must be signed in to star a gist
  • Fork 5 You must be signed in to fork a gist
  • Save dekobon/305883fb6d776b0c9fc1 to your computer and use it in GitHub Desktop.
Save dekobon/305883fb6d776b0c9fc1 to your computer and use it in GitHub Desktop.
Installing Java 8 on SmartOS

Installing the Oracle Java 8 JDK on SmartOS

  1. Go to: http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html
  2. Download the "Solaris x64 XX.X MB jdk-8u66-solaris-x64.tar.gz" tarball from the Oracle Java SE site. You won't be able to paste the URL into curl on your SmartOS instance unless you click it first to get the authentication parameter. Regardless, get the tarball any way that you prefer and copy it onto your SmartOS instance.
  3. Extract the tarball and copy it to the location of your choosing.
  4. Globally set the value of the environment variable JAVA_HOME to the path of the JVM.
  5. Update your PATH to include the Java bin directory by setting it to PATH=$PATH:$JAVA_HOME/bin

Installing the JDK on Linux

Use the appropriate instructions for the Linux distribution.

Configuring the runtime parameters of Java applications in zones

If you are planning on running a Java application in a zone in a system with a lot of physical cores, you will want to configure the JVM's garbage collector to only use a subset of the cores available and to disable CPU affinity (a good idea regardless of how many cores are available if you are running in a zone).

Add the following values to your JAVA_OPTS environment variable or add them as options to the java command:

This disables CPU affinity with the GC. -XX:-UseGCTaskAffinity

This will keep GC threads from being stuck to a single core. -XX:-BindGCTaskThreadsToCPUs

This sets the amount of threads that the GC will use. It is typically set by: ParallelGCThreads = (ncpus <= 8) ? ncpus : 3 + ((ncpus * 5) / 8) If the value of ncpus is very high and you are on a zone, it is very probably that you have over-allocated threads to GC. You should set this to a lower value. -XX:ParallelGCThreads=N

This enables SmartOS/Solaris event port support with NIO on the JVM. This setting is only relevant when running in SmartOS. It may improve the workloads of certain types of server applications and may decrease the performance of other types of workloads. You will need to benchmark and determine if this setting makes sense for your application.

-Djava.nio.channels.spi.SelectorProvider=sun.nio.ch.EventPortSelectorProvider

Large Page Size Support SmartOS and Linux support large pages. The advantage of using large pages (2MB instead of 4KB) is that they use less TLB (translation lookaside buffer) entries. The TLB is a hardware virtual to physical address cache. It typically has 64 entries, each mapping 1 page of memory. With 4KB pages, this means that at most 256KB is mapped in the TLB at any one time. With a 2MB page, 1 entry maps 2MB (so it’s possible to have the TLB map 128MB). Having said this, due to memory fragmentation, (especially after the system has been up for a while), it is possible that there are no large pages available. A 2MB page requires the physical memory to to be physically contiguous, and aligned on a 2MB physical address.

To see what’s supported, you can use the following:

# /native/usr/bin/pagesize -a
4096
2097152
1073741824
#

So 4KB, 2MB, and 1GB page sizes are supported. To request large pages, use ppgsz(1), for example:

# /native/usr/bin/ppgsz -o heap=2M -p $$

The above tries to set heap page size to 2MB.

If your app uses large pages and they are shown as available via the commands above, then you can set them using: -XX:+UseLargePages

ForkJoinPool The fork join pool setting sets the amount of threads available when running Java streams in parellel mode. -Djava.util.concurrent.ForkJoinPool.common.parallelism=ceil(cpu_cap / 100)

When there are all chained together, it will look like:

JAVA_OPTS="-XX:-UseGCTaskAffinity -XX:-BindGCTaskThreadsToCPUs -XX:ParallelGCThreads=4 -Djava.util.concurrent.ForkJoinPool.common.parallelism=4 -Djava.nio.channels.spi.SelectorProvider=sun.nio.ch.EventPortSelectorProvider"

It is important to note that the JVM's implementation or non-implementation of the -XX flags above can change from subversion to subversion or upon platform. It doesn't hurt anything for the flags to be present if the JVM doesn't honor them. For example, the Linux JVM doesn't use the -UseGCTaskAffinity flag, but the Solaris JVM does. Nonetheless, I always set the -UseGCTaskAffinity when running JVMs in Linux zones because it is very possible that at some point that "feature" may become enabled when I upgrade my JVM.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment