如何确定Java堆是否使用压缩指针,以及是否驻留在内存中地址0处?

f2uvfpb9  于 2023-04-19  发布在  Java
关注(0)|答案(4)|浏览(187)

我正试图跟进这个博客www.example.com中的一些技巧https://www.elastic.co/blog/a-heap-of-trouble#ref5,其中讨论了调整Java堆大小的好处,以便(a)可以使用压缩指针(对于32 GB以下的堆)和(B)使堆驻留在内存中的地址0。文章详细介绍了压缩指针如何允许更有效地使用堆空间,并解释了当堆位于地址0时,这减少了解析指针地址所需的算术量。最后,文章说,如果我使用JVM选项-XX:+UnlockDiagnosticVMOptions-XX:+PrintCompressedOopsMode,我将看到如下日志输出:
heap address: 0x000000011be00000, size: 27648 MB, zero based Compressed Oops
表示启用了从零开始的压缩oop,或输出如下所示
heap address: 0x0000000118400000, size: 28672 MB, Compressed Oops with base: 0x00000001183ff000
其指示堆开始于除零以外的地址,因此需要上述增加量的算术处理。
然而,当我尝试这些选项并grep'd通过我的应用程序的(ElasticSearch的)日志目录时,我找不到这样的消息。如果有人能告诉我如何强制记录从零开始(或不从零开始)的压缩指针的细节,我将非常感激。
决议:
很棒的答案!..我接受了@apangin的,我把他提供的java程序 Package 在一个shell脚本中,只要你有java..如果你正在看Java堆,你应该这样做!下面是脚本:https://github.com/buildlackey/scripts/blob/master/verify_compressed_pointers_from_zero_offset.sh

kdfy810k

kdfy810k1#

假设您使用的是Linux和ES 5.x及更高版本。
在整个集群中收集信息的最有效方法是使用the nodes info API
curl -XGET“http://localhost:9200/_nodes/jvm?filter_path=nodes .*.jvm.using_compressed_ordinary_object_pointers”
Copyright © 2018 - 2019 www.jydcxbpT2SBKc4dTfOYsA. All Rights Reserved.京ICP备15004888号-1京公网安备11010502000118号
相同的信息记录在主日志中-/var/log/elasticsearch/elasticsearch.log
[2017-10- 06 T23:03:15,223][INFO ][o.e.e.NodeEnvironment ] [-jYDCxb]堆大小[1.9gb],压缩普通对象指针[true]
如果你对真实的的JVM输出感兴趣,那么你必须知道,默认情况下,JVM会将其消息写入标准输出,而在Linux发行版上,默认情况下,此输出被配置为重定向到journalctl。所以你有两个选择。第一个是读取journalctl:
sudo journalctl -u elasticsearch.service
窄klass底座:0x 000000000000000,窄klass移位:3压缩类空间大小:1073741824地址:0x 000000010000000请求地址:0x0000000100000000
但有时journalctl默认禁用,您必须通过从ES命令行参数中删除--quite参数来更改守护进程配置/usr/lib/systemd/system/elasticsearch.service中的此设置。第二种方法是最简单的跨平台-将JVM消息重定向到特定的GC日志输出:
-XX:+UnlockDiagnosticVMOptions -XX:+PrintCompressedOopsMode-Xloggc:/tmp/vm.log
现在您可以在/tmp/vm.log中看到所有与GC相关的输出

9w11ddsr

9w11ddsr2#

HotSpot Serviceability Agent可以在正在运行的JVM进程上显示这一点,即使不需要额外的命令行标志。
以目标Java进程ID作为参数运行以下程序。

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);
    }
}

在JDK 9之前,这需要在类路径中包含${JDK_HOME}/lib/sa-jdi.jar。程序需要在与运行目标进程相同的JVM版本下运行。

vmdwslir

vmdwslir3#

然而,当我尝试这些选项并通过我的应用程序(ElasticSearch)的日志目录grep时,我找不到这样的消息。
可能是因为它只将应用程序消息记录到该目录中。您还需要将JVM输出记录到一个文件中,或者检查stdout或stderr以获取这些消息。

tktrz96b

tktrz96b4#

boolean compressedOopsEnabled = Boolean.parseBoolean(java.lang.management.ManagementFactory
    .getPlatformMXBean(com.sun.management.HotSpotDiagnosticMXBean.class)
    .getVMOption("UseCompressedOops").getValue());

相关问题