JVM Profiler StacktraceCollectorProfiler

简介: 开篇 StacktraceCollectorProfiler主要用来采集线程的调用栈,原理是通过ManagementFactory.getThreadMXBean()返回的ThreadMXBean对象来实现。

开篇

 StacktraceCollectorProfiler主要用来采集线程的调用栈,原理是通过ManagementFactory.getThreadMXBean()返回的ThreadMXBean对象来实现。

源码分析

    public void profile() {
        // 获取此刻所有线程的dump信息
        ThreadInfo[] threadInfos = threadMXBean.dumpAllThreads(false, false);
        if (threadInfos == null) {
            return;
        }
        
        // 遍历线程信息并处理每个线程
        for (ThreadInfo threadInfo : threadInfos) {
            String threadName = threadInfo.getThreadName();
            if (threadName == null) {
                threadName = "";
            }
            
            if (!ignoreThreadNamePrefix.isEmpty()
                    && threadName.startsWith(ignoreThreadNamePrefix)) {
                continue;
            }
            
            // 获取线程的调用栈
            StackTraceElement[] stackTraceElements = threadInfo.getStackTrace();

            // 创建调用栈对象
            Stacktrace stacktrace = new Stacktrace();
            stacktrace.setThreadName(threadName);
            stacktrace.setThreadState(String.valueOf(threadInfo.getThreadState()));

            // 创建保存调用栈的list
            int totalLength = 0;
            List<ClassAndMethod> stack = new ArrayList<>(stackTraceElements.length);
            // 按照倒序保存调用链,最底层的放在最前面,把最根本的原因发在前面
            for (int i = stackTraceElements.length - 1; i >= 0; i--) {
                StackTraceElement stackTraceElement = stackTraceElements[i];
                String className = String.valueOf(stackTraceElement.getClassName());
                String methodName = String.valueOf(stackTraceElement.getMethodName());
                stack.add(new ClassAndMethod(className, methodName));

                totalLength += className.length() + methodName.length();
                // 如果长度超出限制,那么就截断
                if (totalLength >= Constants.MAX_STRING_LENGTH) {
                    stack.add(new ClassAndMethod("_stack_", "_trimmed_"));
                    break;
                }
            }
            
            // 反转调用链,把最底层的放在最前面。
            ClassAndMethod[] classAndMethodArray = new ClassAndMethod[stack.size()];
            for (int i = 0; i < stack.size(); i++) {
                classAndMethodArray[classAndMethodArray.length - 1 - i] = stack.get(i);
            }
            
            stacktrace.setStack(classAndMethodArray);
            
            buffer.appendValue(stacktrace);
        }
    }


采集结果

调用链的反向序列为:

  • java.lang.Thread.sleep
  • com.uber.profiling.examples.HelloWorldApplication.privateSleepMethod
  • com.uber.profiling.examples.HelloWorldApplication.main
{
    "stacktrace": ["java.lang.Thread.sleep", "com.uber.profiling.examples.HelloWorldApplication.privateSleepMethod", "com.uber.profiling.examples.HelloWorldApplication.main"],
    "endEpoch": 1536072801080,
    "appId": null,
    "host": "xiaozhideMacBook-Pro.local",
    "name": "2203@xiaozhideMacBook-Pro.local",
    "processUuid": "1e580f6e-0493-4e5b-bee2-a61c5f7b097d",
    "threadState": "TIMED_WAITING",
    "count": 24,
    "tag": "mytag",
    "startEpoch": 1536072796084,
    "threadName": "main"
}
目录
相关文章
|
分布式计算 监控 Java
Uber jvm profiler 使用
Uber jvm profiler 使用
287 0
Uber jvm profiler 使用
|
存储 SQL 分布式计算
如何用 Uber JVM Profiler 等可视化工具监控 Spark 应用程序?
  关键要点   持续可靠地运行 Spark 应用程序是一项具有挑战性的任务,而且需要一个良好的性能监控系统。   - 在设计性能监控系统时有三个目标——收集服务器和应用程序指标、在时序数据库中存储指标,并提供用于数据可视化的仪表盘。   Uber JVM Profiler 被用于监控 Spark 应用程序,用到的其他技术还有 InfluxDB(用于存储时序数据)和 Grafana(数据可视化工具)。性能监控系统可帮助 DevOps 团队有效地监控系统,用以满足应用程序的合规性和 SLA。
271 0
|
监控 Java 调度
JVM Profiler 启动过程分析
开篇  先来调侃一句,原来独角兽Uber的程序员写的代码也是看得懂的,而且还是比较容易看得懂的,所以有时候在设计模式和代码结构清晰以及可读性方面我还是更倾向于后者,宁可重复或浪费一部分代码也要整个代码的可读性更强一些。
1157 0
|
数据采集 Linux 索引
JVM Profiler IOProfiler
开篇  IOProfiler因为采集方法的限制,目前支持linux系统指标采集,但是不支持mac,windows等操作系统。  IOProfiler通过读取linux系统的/proc/self/io的当前线程的IO指标数据,该文件的内容如下图所示,通过解析成kv键值对完成采集。
1036 0
|
Java
JVM Profiler CpuAndMemoryProfiler
开篇   CpuAndMemoryProfiler主要用来采集cpu和memory相关的信息,采集核心方法都是由ManagementFactory提供的接口: getClassLoadingMXBean() 返回 Java 虚拟机的类加载系统的管理 Bean。
893 0
|
监控 Java 编解码
JVM Profiler 方法耗时采集
开篇  JVM Profile的方法采集通过修改字节码在原来方法体的前置和后置增加采集耗时的代码。核心是基于基于java自带的instrument包和javassist包来实现的。
1181 0
|
NoSQL Java Redis
JVM Profiler Reporter介绍
开篇  JVM Profiler采集完数据后可以通过多种途径上报数据,对接Console,File,redis,kafka等,这篇文章会把源码罗列一下毕竟都很简单。
1174 0
|
消息中间件 分布式计算 Java
JVM Profiler介绍
开篇  过去的几周把java多线程相关部分的源码粗粗的看了一遍基本上也算告一段落了,后面应该会聚焦看下dubbo、mycat、datax以及剩下部分的mybatis。
1716 0
|
监控 Java 消息中间件
JVM Profiler 整体架构
开篇 整个JVM Profiler的组件类似于上图,抽象出来主要分为:Class File Transformer:负责转换被监控方法的字节码,在前后增加耗时统计。
1060 0
|
1月前
|
存储 安全 Java
jvm 锁的 膨胀过程?锁内存怎么变化的
【10月更文挑战第3天】在Java虚拟机(JVM)中,`synchronized`关键字用于实现同步,确保多个线程在访问共享资源时的一致性和线程安全。JVM对`synchronized`进行了优化,以适应不同的竞争场景,这种优化主要体现在锁的膨胀过程,即从偏向锁到轻量级锁,再到重量级锁的转变。下面我们将详细介绍这一过程以及锁在内存中的变化。
37 4