Skip to content

Configuring your system

Configuring your local system can help you optimize the runtime environment for your Java application. Options include setting operating system environment variables and configuring system resources so that OpenJ9 can exploit the underlying operating system and hardware capabilities.

When you install a Java™ runtime environment on your system you can set the PATH environment variable so that the operating system can find the Java programs and utilities to run your application. To tell your application where to find user classes, you can use the -cp option or set the CLASSPATH environment variable. However, if you set CLASSPATH globally, all invocations of Java are affected. How to set these environment variables is covered in many publications about Java, such as The Java Tutorials: PATH and CLASSPATH.

On some systems, a further environment variable might be required if your application requires shared libraries but does not specify their exact location. You can set the following environment variables to specify the directory location of the shared libraries, although setting a global value affects all invocations of Java:

  • LIBPATH (AIX®)
  • LD_LIBRARY_PATH (Linux®)
  • DYLD_LIBRARY_PATH (macOS®)
  • PATH (Windows®)

Start of content that applies to Java 14+ Although most Java applications should run without changing anything on the underlying system, a unique pre-requisite exists for AIX systems on OpenJDK version 14 and later; you must have the XL C++ Runtime installed. End of content that applies only to Java 14 and later

Setting resource limits (AIX, Linux, and macOS)

The operating system sets resource limits for a shell, and to processes started by the shell, to ensure that a single process cannot consume all available resources. However, these limits can affect certain operations that might need to run for a Java application, such as producing a dump file.

Setting ulimit values

Some resource limits are controlled by the ulimit command. A soft limit is the value set by the kernel for a resource and a hard limit imposes a maximum value on the soft limit. A privileged process can change either limit, but an unprivileged process can change only its soft limit (between 0 and the hard limit) or irreversibly lower its hard limit. To see the current limits set for a system, run ulimit -a. The output is similar to the following example:

core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
file size               (blocks, -f) unlimited
max locked memory       (kbytes, -l) unlimited
max memory size         (kbytes, -m) unlimited
open files                      (-n) 256
pipe size            (512 bytes, -p) 1
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 2784
virtual memory          (kbytes, -v) unlimited

To show hard limits, use ulimit -Ha.

You can change limits for specific resources on a temporary basis by running the ulimit command. Alternatively, you can store limit settings in a configuration file, which is /etc/security/limits for AIX or etc/security/limits.conf for Linux. For more information about configuring resource limits, refer to the documentation for your operating system.

The main use case for changing ulimit resources is when enabling a system dump to ensure that all the required data can be collected for analysis. For more information, see Enabling a full system dump.

Setting shared memory values

Another use case for changing resource limits is to ensure that there is sufficient shared memory allocated for class data sharing. By default, the shared classes cache consists of memory-mapped files that are created on disk and persist when the system is restarted. If you choose to use non-persistent caches by setting the -Xshareclasses:nonpersistent option, caches are not retained on startup and are allocated by using the System V IPC shared memory mechanism.

  • On AIX systems, the kernel dynamically adjusts the shared memory settings as required. No special configuration is required.
  • On Linux systems, the SHMMAX setting limits the amount of shared memory that can be allocated, which affects the shared classes cache size. You can find the value of SHMMAX for your system in the /proc/sys/kernel/shmmax file. For non-persistent caches, set this value to an appropriate size for your applications. To make these changes permanent, edit /etc/sysctl.conf and reboot your system.
  • On macOS systems, you must set kern.sysv.shmmax and kern.sysv.shmall when using a nonpersistent cache. Modify the settings in your /etc/sysctl.conf file and reboot your system. To check the value, run sysctl kern.sysv.shmmax.

Note: The virtual address space of a process is shared between the shared classes cache and the Java heap. Increasing the maximum size for the shared classes cache might reduce the size of the Java heap that you can create.

Shared memory limits are also important when configuring large page memory allocation on Linux systems. For more information, see Configuring large page memory allocation: Linux systems.

Configuring large page memory allocation

If your application allocates a large amount of memory and frequently accesses that memory, you might be able to improve performance by enabling large page support on your system.

Some Linux kernels implement Transparent HugePage Support (THP), which automates the provision of large pages to back virtual memory, as described in Linux systems. Alternatively, you can enable large page support by setting the -Xlp:objectheap and -Xlp:codecache options on the command line when you start your application. These options have the following effects:

  • The -Xlp:objectheap option requests that the Java object heap is allocated by using large pages.
  • The -Xlp:codecache option requests that the JIT code cache is allocated by using large pages.

You must also enable large pages on your local system. This process differs according to the operating system.

AIX systems

AIX supports large page sizes of 64 KB and 16 MB, and a huge page size of 16 GB depending on the underlying system P hardware. To determine which page sizes are supported on a particular system, run pagesize -a.

To use large pages to back an application's data and heap segments, specify the LDR_CNTRL environment variable. You can set different page sizes for different purposes. The following variables can be used:

  • TEXTPSIZE: Page size to use for text
  • STACKPSIZE: Page size to use for stacks
  • DATAPSIZE: Page size to use for native data or HEAP64

The following example sets 4 KB for text and 64 KB for stack, native data, and heap areas:

LDR_CNTRL=TEXTPSIZE=4K@STACKPSIZE=64K@DATAPSIZE=64K

For more information, including support considerations, see Large pages and Multiple page size support in the AIX documentation.

The 16 MB and 16 GB page sizes, which are intended for very high performance environments, require special user permissions. You must also configure the number of pages that you require, which cannot be adjusted on demand. For 16 MB large pages, you set the number of large pages by using the vmo command. For 16 GB huge pages you must define the number of pages by using the hardware management console. For more information, see Page sizes for very high-performance environments in the AIX documentation.

Linux systems

Large pages are typically referred to as huge pages on Linux systems. To configure huge page memory allocation, the kernel must support huge pages. If huge pages are supported, the following lines are present in the /proc/meminfo file:

HugePages_Total:    
HugePages_Free:     
Hugepagesize:     

If these lines do not exist, update your Linux kernel. If HugePages_Total has a value of 0, huge pages are available, but not enabled. To enable huge pages, add the following line to your /etc/sysctl.conf file and reload the configuration by running sysctl -p:

vm.nr_hugepages=<number>

Where <number> is the number of huge pages required.

Configure the number of huge pages that you require at boot time to ensure that the VM has access to sufficient contiguous pages. The following kernel parameters must be set appropriately for your system:

  • SHMMAX: The maximum size of the shared memory segment (bytes).
  • SHMALL: The total amount of shared memory in the system (bytes or pages).

The user running the Java process must either be ROOT or have permissions to use huge pages. For the appropriate permissions, the user must be a member of a group that has its group identifier (gid) stored in /proc/sys/vm/hugetlb_shm_group. The locked memory limit must also be increased to at least the size of the Java heap by using the ulimit -l command.

Where huge page support is available, the following default sizes apply for the object heap:

  • Linux on x86: 2 MB
  • Linux on IBM Power Systems: Varies depending on kernel version, check /proc/meminfo
  • Linux on IBM Z: 1 MB

Transparent HugePage Support (THP) is an automated mechanism of using huge pages to back virtual memory. On Linux kernels that support THP, it is typically enabled by default with the madvise option and can be relied on to provide huge pages as required without any user configuration. To disable THP for your application, use the OpenJ9 -XX:-TransparentHugePage option on the command line. To disable THP system-wide, change the sysfs boot time defaults with the command transparent_hugepage=never. For more information about THP see Transparent HugePage Support.

Windows systems

On Windows systems, large pages are typically 2 MB in size. To use large pages, the VM user must have the Windows Lock pages in memory setting enabled in the Local Security Policy. Applications must also be run with Admin privileges in order to use large page memory allocations.

For more information, see the following resources from Microsoft:

z/OS systems

When available, 1 MB pageable pages are the default size for the object heap and the code cache. Other page sizes are available for the object heap, depending on the system architecture as shown in the following table:

Large page size System architecture required -Xlp:codecache -Xlp:objectheap
2 GB nonpageable IBM zEnterprise EC12 processor or later Not supported Supported (64-bit VM only)
1 MB nonpageable System z10 processor or later Not supported Supported (64-bit VM only)
1 MB pageable IBM zEnterprise EC12 processor or later (see Note) Supported Supported

Note: The Flash Express feature (#0402) helps avoid demoting 1 MB pageable pages to 4 KB pages when there is system paging activity.

If a particular page size cannot be allocated, a smaller page size is attempted, in descending order. For example, if 2 GB nonpageable pages are requested but not available, the VM tries to allocate 1MB nonpageable pages. If 1 MB nonpageable pages are not available, the VM tries to allocate 1MB pageable pages. If large pages are not available, 4 KB pages are allocated.

If you want to use nonpageable large pages for the object heap, a system programmer must configure z/OS for nonpageable large pages in the IEASYSxx parmlib member. Users who require large pages must also be authorized to the IARRSM.LRGPAGES resource in the RACF FACILITY class with read authority.

Use the following z/OS system command to show large page usage for an LPAR:

MODIFY AXR,IAXDMEM

For more information, see Displaying real storage memory statistics in the z/OS product documentation.

For usage information, including examples, see -Xlp:objectheap.

Configuring Dynamic LPAR support (AIX only)

Dynamic logical partitioning (DLPAR) provides a mechanism to add or remove system resources, such as memory or CPU, to or from the operating system in a logical partition without rebooting. Changing these resources dynamically can have an impact on Java applications that are running on the LPAR.

To enable an application to respond to DLPAR events, you can use OpenJ9 MXBean extensions to the java.lang.management API. The following classes are available in the com.ibm.lang.management package:

  • AvailableProcessorsNotificationInfo: Use to listen for changes to the number of available processors.
  • ProcessingCapacityNotificationInfo: Use to listen for changes to processing capacity.
  • TotalPhysicalMemoryNotificationInfo: Use to listen for changes to the total amount of physical memory that is available.

These extensions can listen for events and trigger any necessary adjustments to the runtime environment. For example, if a Java VM is running in an LPAR with 2GB of memory, but the available memory might be adjusted between 1GB and 8GB, you might set the following options for the Java heap at run time:

–Xms1g –Xsoftmx2g –Xmx8g

This command-line string sets an initial heap size of 1 GB, a soft (adjustable) maximum heap size of 2 GB, and a maximum heap size of 8 GB. You can then use the MemoryMXBean API to dynamically respond to changes in memory resources. The following classes can be used:

  • getMaxHeapSize(): Query the maximum heap size.
  • isSetMaxHeapSizeSupported(): Query whether the VM can support dynamic updates.
  • setMaxHeapSize(): Adjust the maximum heap size.

For more information about the com.ibm.lang.managment package, which extends the jdk.management module, see the API documentation.