Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I am trying to follow up on some tips in this blog https://www.elastic.co/blog/a-heap-of-trouble#ref5 which discusses the benefits of sizing one's Java heap so that (a) compressed pointers can be used (for heaps under 32GB) and (b) so that the heap resides at address 0 in memory. The article details how compressed pointers allow more efficient use of heap space, and explains that when the heap lives at address zero this reduces the amount of arithmetic necessary to resolve pointer addresses. Finally, the article says that if I use JVM options -XX:+UnlockDiagnosticVMOptions -XX:+PrintCompressedOopsMode I will see log output either like this:

heap address: 0x000000011be00000, size: 27648 MB, zero based Compressed Oops

which indicates zero-based compressed oops are enabled, or output like this

heap address: 0x0000000118400000, size: 28672 MB, Compressed Oops with base: 0x00000001183ff000

Which indicates that the heap begins at an address other than zero, therefore requiring the aforementioned increase amount of arithmetic processing.

However, when I tried those options and grep'd through my application's (Elastic Search's) log directory I could find no such messages. If anyone could advise me on how I can force details of zero-based (or not zero based) compressed pointers to be logged I'd be very grateful.

RESOLUTION:

great answers !.. I accepted @apangin's and I wrapped the java program he provided in a shell script that can run as long as you have java.. which you should if you are looking at Java heap! here is the script: https://github.com/buildlackey/scripts/blob/master/verify_compressed_pointers_from_zero_offset.sh

like image 342
Chris Bedford Avatar asked Jan 30 '23 11:01

Chris Bedford


1 Answers

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

like image 149
Ivan Mamontov Avatar answered Feb 02 '23 11:02

Ivan Mamontov