how to determine if Java heap is using compressed pointers and whether or not resides at address 0 in memory? how to determine if Java heap is using compressed pointers and whether or not resides at address 0 in memory? elasticsearch elasticsearch

how to determine if Java heap is using compressed pointers and whether or not resides at address 0 in memory?


Assume you are using Linux and ES with version 5.x and higher.

The most efficient way to gather information across the whole cluster is to use the nodes info API:

curl -XGET "http://localhost:9200/_nodes/jvm?filter_path=nodes.*.jvm.using_compressed_ordinary_object_pointers"

{"nodes":{"-jYDCxbpT2SBKc4dTfOYsA":{"jvm":{"using_compressed_ordinary_object_pointers":"true"}}}}

The same information is logged into the main log - /var/log/elasticsearch/elasticsearch.log

[2017-10-06T23:03:15,223][INFO ][o.e.e.NodeEnvironment ] [-jYDCxb] heap size [1.9gb], compressed ordinary object pointers [true]

If you are interested in the real JVM output then you have to know that by default JVM writes it's messages into standard output and on Linux distributions this output by default is configured to redirect to journalctl. So you have two choices. The first one is to read the journalctl:

sudo journalctl -u elasticsearch.service

Narrow klass base: 0x0000000000000000, Narrow klass shift: 3 Compressed class space size: 1073741824 Address: 0x0000000100000000 Req Addr: 0x0000000100000000

But sometimes journalctl disabled by default and you have to change this setting in the daemon config /usr/lib/systemd/system/elasticsearch.service by removing --quite parameter from ES command line parameters. The second approach is the simplest and cross platform - redirect JVM message to particular GC log output:

-XX:+UnlockDiagnosticVMOptions -XX:+PrintCompressedOopsMode -Xloggc:/tmp/vm.log

Now you can see all GC related output in /tmp/vm.log


HotSpot Serviceability Agent can show this on a running JVM process even with no extra command-line flags required.

Run the following program with the target Java process ID as an argument.

import sun.jvm.hotspot.runtime.VM;import sun.jvm.hotspot.tools.Tool;public class CompressedOopsInfo extends Tool {    @Override    public void run() {        VM vm = VM.getVM();        System.out.println("CompressedOops = " + vm.isCompressedOopsEnabled());        System.out.println("CompressedClassPointers = " + vm.isCompressedKlassPointersEnabled());        System.out.println("OOP base = 0x" + Long.toHexString(vm.getDebugger().getNarrowOopBase()));        System.out.println("OOP shift = " + vm.getDebugger().getNarrowOopShift());    }    public static void main(String[] args) {        new CompressedOopsInfo().execute(args);    }}

Prior to JDK 9 this requires including ${JDK_HOME}/lib/sa-jdi.jar in the classpath. The program needs to run under the same JVM version as used to run the target process.


However, when I tried those options and grep'd through my application's (Elastic Search's) log directory I could find no such messages.

Probably because it only logs application messages to that directory. You need to log JVM output to a file too or inspect stdout or stderr for those messages.