Coder Social home page Coder Social logo

kylixs / flare-profiler Goto Github PK

View Code? Open in Web Editor NEW
65.0 3.0 10.0 9.74 MB

A Java profiler base on jvmti, with chrome flamegraph and slow method analysis. Java性能分析利器,欢迎加QQ群学习交流(837682428)

License: MIT License

Rust 10.27% Batchfile 0.17% Shell 0.14% Java 0.17% HTML 0.34% JavaScript 84.47% Vue 0.99% CSS 3.40% Python 0.05%
jvmti jvm java profiler java-profiler flamegraph peformance-analytics rust

flare-profiler's Introduction

Flare Profiler

English Document

一个基于JVMTI技术的Java诊断工具,支持快速分析JVM线程CPU时间及方法调用栈,集成了灵活好用的动态火焰图组件,Java服务性能优化利器。

当你遇到以下类似的问题时,Flare Profiler可以帮助你解决问题:

  • Java服务在高并发时存在瓶颈,吞吐量较低,无从下手
  • 某些计算任务耗时很长,处理逻辑非常复杂,难以分析
  • 线上服务突然变慢,不知道是什么原因导致
  • 某些比较复杂的开源项目或者框架代码分支太多,通过调试来分析比较麻烦
  • 作为架构师,想将性能调优工作下放到业务组,缺少一个简单好用的工具

Flare Profiler 0.1.0 只是一个雏形,有很多好点子还没有细化下来,想收集了解大家在Java性能调优过程遇到的一些疑难问题。
接下来可能做的功能:

  • 完整的带时序的方法调用树,面向学习分析开源项目(区别于通过定时取样获取的部分方法调用栈,而是通过监控方法进入退出获取到完整的带时序的方法调用树,方便回溯分析任意代码分支)
  • 某个时刻的线程调用栈切面,方便分析资源竞争问题
  • 分析线程锁等待时间
  • 分析对象分配情况(计划参考Yourkit Java Profiler的功能,关联创建对象到发生的调用栈上,这个功能非常实用)

关于github下载慢的问题,建议加QQ群(837682428),从群共享文件下载。

使用文档:
入门指南 Quick Start

关键特性

  • 支持带时序的方法调用栈分析,直观准确反映任意一次请求执行的过程
  • 整合了Chrome浏览器开发工具的火焰图组件,支持鼠标缩放、拖动查看方法调用栈,操作流畅,高效快捷
  • 支持实时分析和离线分析,自动分卷保存取样结果
  • 支持多会话,可多人同时使用,可同时接入多个Agent或打开存档
  • 使用Rust语言编写,运行稳定,资源占用低,只需不到20MB内存,适合在容器内或者开发环境使用
  • 支持多平台(Windows, Linux and macOS)

原理介绍

Flare Profiler 系统交互图如下:
系统交互图

主要功能模块
  • flare-agent: 基于JVMTI技术注入JVM进程中运行,负责进行周期采样获取线程CPU时间及线程方法调用栈等数据。后续会增加对象分配、锁检查、GC活动等功能。
  • flare-server: 查询分析服务,负责收集采样数据并保存到本地文件,提供查询分析服务接口,如获取线程CPU时间统计图,获取某个时间范围的线程方法调用栈统计数据等。
  • flare-ui: 诊断分析交互界面,主要包括展示线程CPU时间图表、方法调用栈火焰图等。

功能对比

以下对比常见工具的JVM CPU 诊断功能:

项目 JProfiler Async Profiler Flare Profiler
内存占用 大于512MB 小于20MB
火焰图 不支持 支持,静态SVG 支持,动态缩放、拖动查看
方法调用时序 不支持 不支持 支持直观查看方法执行过程
实时/离线分析 支持实时查看,Agent断开后不能分析 不支持实时查看 支持实时和离线分析
稳定性 压测时JVM可能Crash 压测时仍然稳定运行
兼容性 支持多种平台 不支持Windows 支持Windows、Linux、macOS

常见问题

1、可能超出最大可打开的文件数量(此问题已经解决)
save summary info failed: Too many open files (os error 24)
原因:
Flare Profiler为每个JVM线程创建两个文件,如果JVM线程太多,将导致打开或者保存文件失败。
解决办法:
ulimit -a #查看系统的文件句柄数量设置,如果太少,请改大一点
macOS参考命令:

sudo launchctl limit maxfiles 999999999 999999999  
sudo ulimit -n 65535  
ulimit -n 65535  

2、方法调用栈火焰图(Call Graph标签页)加载异常
火焰图组件来源于Chrome浏览器调试工具项目(devtools),仅支持在Chrome浏览器77以上版本运行,如果出现显示异常请升级Chrome到最新版本或者使用Protable版本。

Links:

Flare Profiler 开源交流QQ群: 837682428,欢迎加群一起探讨学习Java & Rust !
Flare Profiler 开源交流QQ群: 837682428

flare-profiler's People

Contributors

dependabot[bot] avatar kylixs avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

flare-profiler's Issues

分析指定方法下级调用概要情况

场景:
某些方法下级存在大量相类似的方法调用,如查在for循环中查询数据库。
目的:
提供一个下级方法调用分析手段,将下级方法聚合,提供概要视图显示主要问题。
暂定是按照树形展示,相关指标是: duration 百分比, duration汇总时间,方法调用次数,将热点方法排在前面。

支持注入以windows服务方式运行的Java应用

参考Arthas项目的as-service.bat脚本,编写一个用于FlareAgent的服务脚本。
1)接受命令行参数,创建FlareAgent服务,服务binPath附带注入进程或者端口参数
2)启动FlareAgent服务,在服务会话执行脚本,将注入参数传递给start-agent-trace.bat / stop-agent-trace.bat

解决方法分析遗漏非主要分支的方法的问题

场景:
慢方法查找可以识别主要方法分支,但忽略了有价值的次要分支(即使次要分支方法调用时间也大于查找的最小时间,仍然会被忽略)

解决办法:
1)将方法调用特征栈改为树形,列出所有满足条件的分支的方法
-- 可能导致方法调用特征比较庞大,重复率不高,不容易分组
2)将次要分支作为单独的方法调用

统计指定方法名最慢top n个记录

性能压测时经常会出现一个问题,99%的请求响应时间都是很快的,但max响应时间很大,想去分析这些异常的情况。
flare profiler保存了所有请求执行过程的取样信息,基于这些数据自动统计出指定方法最慢top n个记录,点击跳转到对应线程和时刻的线程栈火焰图!
这是一个性能分析的杀手锏!

重构索引数据文件类代码

问题描述:
线程栈数据使用索引数据文件方式保存,当前使用enum来支持动态类型,调试时不能直观观察变量值,出现错误不方便分析。

改进:
1)index类型使用泛型代替enum

支持线程调用栈切面功能

Flare Profiler保存了每个线程的时序调用栈,可以计算到任意时刻的调用栈。虽然存在一定时间误差(采样间隔时间内),但对于问题诊断来说还是有较大的参考意义。

举例来说明:
查看线程调用栈火焰图时,发现某个时刻Logback写日志到文件时等待锁,持续超过1s。
需求:想看一下当时整体的线程调用栈,计算有多少个线程在等待锁,这个对于问题分析有很大意义。

实现方法:
Flare Profiler对每个线程的调用栈是按照增量方式保存,即取样时对比此线程上次的调用栈,如果发生变化则保存一个快照,否则忽略。
所有线程数据的时间都是相对于采样数据的开始收集时间,每个线程的调用栈单独按照发生的顺序保存到文件,同时建立了数据块的索引信息。
假如想要查看时刻t的线程调用栈,根据索引信息可以定位到某一个索引的时刻t1 <= 时刻t,则此索引对应的调用栈快照可以认为该线程时刻t的调用栈。我们知道在取样周期内没有更新,取样周期一般是5ms,对于分析锁等待之类的情况是非常短暂的,没有太大的影响。

监控记录Java进程的os thread cpu usage

1)监控记录Java进程的os thread cpu usage
2)结合 #30 获取的java线程的tid,可以反过来找到os线程tid对于的java线程时序调用栈,可以做出telemetry 遥测数据
3)比较os tid的cpu usage时效性 和 java thread cpu time的差异,期望是os的 tid cpu time更加实时准确。编写testcase,记录热点计算的开始和结束时间,与采集到的线程cpu 时间区间的时刻进行比较。

防止同一个agent被重复连接

同一个agent被flare server重复连接后,可能导致收集的采样数据不准确。

  1. flare server 对相同的地址只能连接一次,发现有相同的地址改为激活
  2. flare agent 只保留最后一个连接,自动关闭之前的连接
  3. 当agent连接断开时,关闭会话(也可能是agent的Java进程结束了)

支持方法特征识别

根据预设的方法特征列表,识别出MySQL、Redis、SpringMVC、Servlet、Struts 等方法,并在显示时标记出来,如使用不同的背景颜色。

添加线程CPU时间统计图数据缓存

问题描述:
每次打开取样数据文件时,都要重新计算一次CPU时间统计图的数据,调试模式下等待较长时间,不方便使用。

改进:
1)已打开的会话,将线程CPU时间统计数据缓存在内存中
2)取样数据文件中增加CPU时间统计图数据缓存文件,如果不存在则创建,有则校验是否正确。
统计图缓存数据格式:
|头部信息(索引开始位置,块数据位置)|
|索引数据,索引数据,...|
|线程信息(id,名称,时间,聚合粒度时间)|聚合数据
|线程信息(id,名称,时间,聚合粒度时间)|聚合数据
...

更换flare-agent 使用的hashmap hash算法

Rust HashMap默认hash算法是防hash碰撞的,速度不是很快。而在Flare Agent的hashmap主要是对methodid,不需要考虑碰撞问题,但要追求极致的性能。

通过增强Thread相关class获取到Java线程对于的OS线程tid

1)编写获取os线程tid的jni native接口
2)通过增强Thread相关class,比如在线程入口方法run()中调用jni 获取os 线程tid的方法
3)将os线程tid保存到线程threadLocal中
4)flare agent取样时读取线程的threadLocal,获取java线程的os线程tid

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.