常见问题

本文介绍持续剖析使用过程中的常见问题。

parse lib sigsegv handler installed日志打印

问题原因

该日志是ARMS探针打印的无用日志,仅在开启持续剖析功能后才会打印,对应用运行过程无影响,另外ARMS会在将来的新版本中关闭相关日志打印。

perf_event_open被限制导致的No access to perf events报错问题

问题现象

Async-Profiler进行CPU Profiler依赖perf_event_open的系统调用,但因为Linux kernelSyscall安全策略(seccomp)控制,可能会禁止进程调用特定Syscall。

错误提示如下:

[ERROR] Failed to execute 'start,jfr=0,event=cpu,interval=11ms,alloc=512k,file=/tmp/cpc-async-profiler-7729534006755968198.jfr'
[ERROR] Failed to start Continuous Profile Collector
java.lang.RuntimeException: java.lang.IllegalStateException: No access to perf events. Try --fdtransfer or --all-user option or 'sysctl kernel.perf_event_paranoid=1'

解决方案

  • Docker环境:执行以下命令运行容器。如需配置更精细化的系统调用控制,请参见官方文档

      docker run --security-opt seccomp=unconfined  XXX
  • Kubernetes环境:配置特权容器参数privileged: true,特权容器始终保持为Unconfined

    如需配置更精细化的系统调用控制,请参见官方文档

No AllocTracer symbols found .Are JDK debug symbols installed?报错问题

问题现象

Async-Profiler进行内存剖析需要依赖JDK的符号信息,如果JDK内无符号信息,则会遇到如下问题:

[ERROR] Failed to start Continuous Profile Collector
java.lang.RuntimeException: java.lang.IllegalStateException: No AllocTracer symbols found. Are JDK debug symbols installed?

解决方案

如果Java进程运行在容器环境,出现以上报错或者该功能无数据,一般都是由于使用了Alpine基础镜像导致,Alpine基础镜像为了控制体积而去除了JDK调试符号(debug symbols),影响持续剖析能力正常使用,建议在基础镜像中为JDK安装调试符(部分JDK版本缺乏对应的调试符包,会导致无法安装)或使用非Alpine基础镜像。

如果是CentOS物理机环境部署应用可通过以下步骤安装调试符:

  1. 执行以下命令,确认是否已经配置了debuginfo的源。

    yum repolist all | grep -i debug

    通过返回信息确认源配置信息是否如下:

    debuginfo/7/x86_64 CentOS-7 - debuginfo - mirrors.aliyun.com 启用: 8,760

    如果未配置debuginfo的源,则执行步骤2增加配置;如果已经配置,则执行步骤3

  2. Yum配置文件中增加debuginfo的配置。

    vi /etc/yum.repos.d/CentOS-Base.repo
    [debuginfo]
    name=CentOS-$releasever - debuginfo - mirrors.aliyun.com
    failovermethod=priority
    baseurl=http://mirrors.aliyun.com/centos-debuginfo/$releasever/$basearch/
    gpgcheck=1
    enabled=1
    gpgkey=http://mirrors.aliyun.com/centos/RPM-GPG-KEY-CentOS-Debug-7

    保存后执行如下命令:

    yum clean all
    yum makecache
    yum-config-manager --enable debuginfo
  3. 安装JDK版本对应的符号信息。

    JDK 8

    yum list installed|grep openjdk    #查询JDK版本。
    java-1.8.0-openjdk.x86_64          1:1.8.0.332.b09-1.el7_9            @updates
    
    debuginfo-install -y java-1.8.0-openjdk      #安装符号信息。

    JDK 11

    yum list installed|grep openjdk    #查询JDK版本。
    java-11-openjdk.x86_64             1:11.0.15.0.9-2.el7_9              @updates
    
    debuginfo-install -y java-11-openjdk      #安装符号信息。
  4. 检查JDK的符号信息是否已经安装成功。

    gdb $JAVA_HOME/lib/server/libjvm.so -ex 'info address UseG1GC'
    gdb /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.332.b09-1.el7_9.x86_64/jre/lib/amd64/server/libjvm.so -ex 'info address UseG1GC'
    GNU gdb (GDB) Red Hat Enterprise Linux 7.6.1-120.el7
    Copyright (C) 2013 Free Software Foundation, Inc.
    License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
    This is free software: you are free to change and redistribute it.
    There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
    and "show warranty" for details.
    This GDB was configured as "x86_64-redhat-linux-gnu".
    For bug reporting instructions, please see:
    <http://www.gnu.org/software/gdb/bugs/>...
    Reading symbols from /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.332.b09-1.el7_9.x86_64/jre/lib/amd64/server/libjvm.so...Reading symbols from /usr/lib/debug/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.332.b09-1.el7_9.x86_64/jre/lib/amd64/server/libjvm.so.debug...done.
    done.

    如果安装正确,返回信息如下:

    Symbol "UseG1GC" is static storage at address 0x107f993.

    如果安装失败,返回信息如下:

    No symbol "UseG1GC" in current context.

perf_event mmap failed...报错问题

问题现象

此错误一般出现在JVM的标准输出中。持续剖析功能进行CPU热点采样时,会同时采集Native(Linux Kernel + JVM + C/C++)以及Java栈,采集Native栈需要对Java中每个线程的perf_eventfd进行MMap,Linux内核中限制了进程perf_event相关的MMap的总内存大小(默认516 K Bytes)。当Java中线程数较多时,会触发限制并在Java标准输出中打印警告信息perf_event mmap failed...。出现这个告警信息,对Java的运行没有副作用,对业务也没有影响,实际的影响是火焰图中看不到Native的栈。一般来说定位CPU热点问题时,只看Java方法栈就够了,您可以忽略此告警。

解决方案

如果想消除这个错误信息,可以执行以下步骤:

  1. 在宿主机上执行以下命令。

    echo 1028 > /proc/sys/kernel/perf_event_mlock_kb

    默认阈值是516,可以逐渐增加,直到不出现告警,该值最好满足8*N + 4,N是自然数。例如516 = 512 + 4, 1028 = 1024 + 4。

  2. 重启Docker,即可消除错误。

火焰图中为什么出现other项?

问题现象

如下图所示火焰图中出现other项。

火焰图other选项

问题原因

火焰图中出现other项是正常的。火焰图是一棵树,当节点数较多时不便于从图中提取关键信息,因此ARMS通过一些方法对火焰图中的节点进行收敛,将一些重要性相对较低的节点并入到other项中。

火焰图中为什么出现.no_Java_frame项?

一般是由于使用了Alpine基础镜像,Alpine基础镜像为了控制体积而去除了JDK调试符号(debug symbols),导致JDK里面的C++线程中的方法栈无法识别出函数名字,只能显示为no_Java_frame,由于这些方法栈主要是非Java的线程执行信息,一般常见如VM Thread或者JIT编译器线程,如果no_Java_frame相关内容占比不高,可以忽略,重点观察其他Java方法栈信息做性能分析,如果no_Java_frame相关内容占比较高,建议在基础镜像中为JDK安装调试符(部分JDK版本缺乏对应的调试符包,会导致无法安装)或使用非Alpine基础镜像。