记一次压测程序时的OOM分析过程

这篇具有很好参考价值的文章主要介绍了记一次压测程序时的OOM分析过程。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

景:在一个项目调优的过程中,丰富了一些组件后,再次对项目进行压测,发现和之前的性能差距甚大,并且每次运行一段时间后,延迟骤增,带宽骤降,查看程序日志,发现了 OutOfMemory:java heap memory ;

现在知道了结果是OOM了,why?
逐步对比程序新增内容,未发现会导致OOM的地方,都是一些缓存组件和《监控组件》。

那么只能把OOM是的heap dump出来,一探究竟了。

工具准备

大名鼎鼎

MAT
https://eclipse.dev/mat/downloads.php

我的环境里在linux跑的程序且堆内存为16GB,在本地分析内存不够用,所以用了linux版本的;

下载解压即可,需要修改的vm的配置

**cat MemoryAnalyzer.ini **

-vm 指定本地jdk的路径,最新版需要jdk17+

-Xmx 运行的内存,需要大于hedp.dump的大小

第一次指定的10GB,结果跑了一晚上都没跑完。。。

-vm
/data/apps/jdk17/bin/java
-startup
plugins/org.eclipse.equinox.launcher_1.6.600.v20231106-1826.jar
--launcher.library
plugins/org.eclipse.equinox.launcher.gtk.linux.x86_64_1.2.800.v20231003-1442
-vmargs
--add-exports=java.base/jdk.internal.org.objectweb.asm=ALL-UNNAMED
-Xmx30G  

完事具备,只欠运行了,
导出堆文件可以选用,其他工具亦可:
jmap -dump:format=b,file=heap.hprof pid

heap.hprof是本地的本目录的堆转储文件

nohup ./ParseHeapDump.sh heap.hprof org.eclipse.mat.api:suspects org.eclipse.mat.api:overview org.eclipse.mat.api:top_components &

大概十多分钟后?

查看运行结果

ll -rth 
total 23G
-rw-r--r--  1 root root  17K Jan 23 09:40 epl-2.0.html
drwxr-xr-x 18 root root 4.0K Jan 23 09:40 features
-rwxr-xr-x  1 root root  88K Jan 23 09:40 MemoryAnalyzer
-rw-r--r--  1 root root 9.1K Jan 23 09:40 notice.html
drwxr-xr-x  5 root root 4.0K Jan 23 09:40 p2
-rwxr-xr-x  1 root root  343 Jan 23 09:40 ParseHeapDump.sh
drwxr-xr-x  7 root root  20K Jan 23 09:40 plugins
drwxr-xr-x  3 root root 4.0K Jan 23 09:40 workspace
-rw-------  1 root root  15G Jan 23 09:42 heap.hprof
-rw-r--r--  1 root root  282 Jan 23 09:44 MemoryAnalyzer.ini
drwxr-xr-x  7 root root 4.0K Jan 23 09:44 configuration
-rw-r--r--  1 root root 129K Jan 23 09:45 heap.threads
-rw-r--r--  1 root root 898M Jan 23 09:47 heap.idx.index
-rw-r--r--  1 root root 398M Jan 23 09:47 heap.o2c.index
-rw-r--r--  1 root root 158M Jan 23 09:47 heap.a2s.index
-rw-r--r--  1 root root 1.5G Jan 23 09:49 heap.inbound.index
-rw-r--r--  1 root root 1.6G Jan 23 09:49 heap.outbound.index
-rw-r--r--  1 root root 942M Jan 23 09:49 heap.o2hprof.index
-rw-r--r--  1 root root  19M Jan 23 09:49 heap.index
-rw-r--r--  1 root root 398M Jan 23 09:51 heap.domIn.index
-rw-r--r--  1 root root 676M Jan 23 09:51 heap.o2ret.index
-rw-r--r--  1 root root 1.2G Jan 23 09:52 heap.domOut.index
-rw-r--r--  1 root root 175K Jan 23 09:53 heap_Leak_Suspects.zip
-rw-r--r--  1 root root 129K Jan 23 09:54 heap_System_Overview.zip
-rw-------  1 root root 2.8M Jan 23 10:04 nohup.out
-rw-r--r--  1 root root 449K Jan 23 10:04 heap_Top_Components.zip
-rw-r--r--  1 root root 183K Jan 23 10:04 heap.i2sv2.index

关注三个zip结尾的文件即可

分析

  1. 下载三个zip到有浏览器的机器上即可,主要关注heap_Leak_Suspects.zip

记一次压测程序时的OOM分析过程,JVM,eclipse,jvm,nio

发现了异常的信息,prometheus端点占了1GB+的内存,排到第二名,不可思议。

  1. 再观察heap_System_Overview文件

    记一次压测程序时的OOM分析过程,JVM,eclipse,jvm,nio

发现大量指标类的对象

记一次压测程序时的OOM分析过程,JVM,eclipse,jvm,nio

根因

通过以上的分析,大概定位了问题的起因,新的代码中引入了对于netty相关的mertrics暴露,用于分析性能瓶颈,加入了以下配置代码

@Component
public class WebServerConfig  implements WebServerFactoryCustomizer<NettyReactiveWebServerFactory> {

    @Override
    public void customize(NettyReactiveWebServerFactory factory) {
        //暴露reactor.netty相关指标到端点/actuator/prometheus
        factory.addServerCustomizers(httpServer -> httpServer.metrics(true,(k)-> k));
    }
}

分析mertrics方法的源码如下:

Whether to enable metrics to be collected and registered in Micrometer's globalRegistry under the name reactor.netty.Metrics.HTTP_SERVER_PREFIX.
uriTagValue function receives the actual uri and returns the uri tag value that will be used for the metrics with reactor.netty.Metrics.URI tag. For example instead of using the actual uri "/users/1" as uri tag value, templated uri "/users/{id}" can be used.
Note: It is strongly recommended to provide template-like form for the URIs. Without a conversion to a template-like form, each distinct URI leads to the creation of a distinct tag, which takes a lot of memory for the metrics.
Note: It is strongly recommended applications to configure an upper limit for the number of the URI tags. For example:
  Metrics.globalRegistry
         .config()
         .meterFilter(MeterFilter.maximumAllowableTags(HTTP_SERVER_PREFIX, URI, 100, MeterFilter.deny()));
  
By default metrics are not enabled.
Params:
enable – true enables metrics collection; false disables it uriTagValue – a function that receives the actual uri and returns the uri tag value that will be used for the metrics with reactor.netty.Metrics.URI tag
Returns:
a new HttpServer
Since:
0.9.7
public final HttpServer metrics(boolean enable, Function<String, String> uriTagValue) {
		if (enable) {
			if (!Metrics.isMicrometerAvailable() && !Metrics.isTracingAvailable()) {
				throw new UnsupportedOperationException(
						"To enable metrics, you must add the dependencies to `io.micrometer:micrometer-core`" +
								" and `io.micrometer:micrometer-tracing` to the class path first");
			}

看到源码注释:

Note: It is strongly recommended to provide template-like form for the URIs. Without a conversion to a template-like form, each distinct URI leads to the creation of a distinct tag, which takes a lot of memory for the metrics

意思是说需要为uri设置一个tag,如果不设置就会导致所有的uri都会生成一个mertric,从而占用大量内存,找到根因了,修改后的代码如下

@Component
public class WebServerConfig  implements WebServerFactoryCustomizer<NettyReactiveWebServerFactory> {

    @Override
    public void customize(NettyReactiveWebServerFactory factory) {
        //暴露reactor.netty相关指标到端点/actuator/prometheus
        factory.addServerCustomizers(httpServer ->httpServer.metrics(true,(key)-> "uri" ));
    }
}

到此,问题解决,性能跑到和之前一样的数据。

题外话mertric

从端点/actuator/prometheus中看到,增加以上配置后新增的metric,可以监控uri的一些数据,我们这里只区分了method,因为我们的uri都是pathstyle的形式;文章来源地址https://www.toymoban.com/news/detail-820462.html

# HELP reactor_netty_http_server_data_sent_time_seconds_max  
# TYPE reactor_netty_http_server_data_sent_time_seconds_max gauge
reactor_netty_http_server_data_sent_time_seconds_max{method="GET",status="200",uri="uri",} 0.0
reactor_netty_http_server_data_sent_time_seconds_max{method="GET",status="500",uri="uri",} 0.0
# HELP reactor_netty_http_server_data_sent_time_seconds  
# TYPE reactor_netty_http_server_data_sent_time_seconds summary
reactor_netty_http_server_data_sent_time_seconds_count{method="GET",status="200",uri="uri",} 8309119.0
reactor_netty_http_server_data_sent_time_seconds_sum{method="GET",status="200",uri="uri",} 1846.175749456
reactor_netty_http_server_data_sent_time_seconds_count{method="GET",status="500",uri="uri",} 11.0
reactor_netty_http_server_data_sent_time_seconds_sum{method="GET",status="500",uri="uri",} 0.00846828
erver_data_sent_time_seconds_count{method="GET",status="500",uri="uri",} 11.0
reactor_netty_http_server_data_sent_time_seconds_sum{method="GET",status="500",uri="uri",} 0.00846828

到了这里,关于记一次压测程序时的OOM分析过程的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 记一次应用程序池崩溃问题分析

    IIS部署的asp.net core服务,前端进行一些操作后,经常需要重新登陆系统。 根据日志,可以看到服务重新进行了初始化,服务重启应该与IIS应用程序池回收有关,查看IIS相关日志,在windows的事件查看器=Windows日志=系统,来源为WAS的日志(参考博客)。 根据IIS日志与服务日志对比

    2024年02月04日
    浏览(46)
  • 记一次 .NET 某餐饮小程序 内存暴涨分析

    前些天有位朋友找到我,说他的程序内存异常高,用 vs诊断工具 加载时间又太久,让我帮忙看一下到底咋回事,截图如下: 确实,如果dump文件超过 10G 之后,市面上那些可视化工具分析起来会让你崩溃的,除了时间久之外这些工具大多也不是用懒加载的方式,比如 dotmemory

    2024年02月08日
    浏览(47)
  • 记一次 .NET某工控 宇宙射线 导致程序崩溃分析

    为什么要提 宇宙射线 , 太阳耀斑 导致的程序崩溃呢?主要是昨天在知乎上看了这篇文章:莫非我遇到了传说中的bug? ,由于 rip 中的0x41变成了0x61出现了bit位翻转导致程序崩溃,截图如下: 下面的评论大多是说由于 宇宙射线 ,这个太玄乎了,说实话看到这个 传说bug 的提法

    2024年02月04日
    浏览(43)
  • 记一次“nvidia-smi”在容器中映射GPU资源时的排错

    在云渲染容器组pod中,有xx,xx,xx,unity四个container容器组成,然后因为unity容器镜像的构成是基于vlukan(cudagl相关)和cuda-base打包的,这里的cuda是nvidia的一个驱动版本,类似显卡驱动。现象是启动unity容器后无法运行nvidia-smi和vlukaninfo 初步排查: 因为容器化运行需要依赖宿

    2024年02月03日
    浏览(32)
  • 记一次 .NET某MES自动化桌面程序 卡死分析

    前些天有位朋友在微信上找到我,说他们的客户端程序卡死了,让我帮忙看下是什么原因导致的?dump也拿到了手,既然有了dump就开始正式分析吧。 客户端的程序卡死比较好找原因,入手点就是主线程,看下它此时正在做什么,可以用 k 命令。 从卦中信息看,代码正在托管层

    2024年01月16日
    浏览(44)
  • 记一次pip下载包报错ERROR: No matching distribution found for xxx时的解决方案

    前言 当我们使用python自带的pip安装一些包时,可能会报以下错误: 出现这种情况有三种可能: 第一种可能: pip的版本过低,需要升级一下,可以执行以下命令进行尝试 第二种可能: 考虑可能是网速的原因,这时可以采用国内的镜像源来加速 第三种可能: 检查下是否开启

    2024年02月11日
    浏览(58)
  • 记一次centos 磁盘挂载过程

    最近买了云服务器磁盘,需要挂载,一下就由大猿来记录这次过程。 查看磁盘挂载情况 查看物理硬盘 标记分区 格式化分区 xfs ext4 xfs 和 ext4 区别 在大多数情况下,ext4和xfs都具有较高的性能,可以满足一般的存储需求。 对于大文件读写和吞吐量要求较高的场景,xfs表现更为

    2024年02月14日
    浏览(38)
  • 记一次Kafka重复消费解决过程

            起因:车联网项目开发,车辆发生故障需要给三个系统推送消息,故障上报较为频繁,所以为了不阻塞主流程,采用了使用kafka。消费方负责推送并保存推送记录,但在一次压测中发现,实际只发生了10次故障,但是推送记录却有30多条。         问题排查,发现

    2024年02月13日
    浏览(55)
  • 记一次 stackoverflowerror 线上排查过程

         xxx 日,突然收到线上日志频繁告警 classCastException .从字面上的报警来看,仅仅是类型转换异常,查看细则发现其实是 stackOverFlowError .很多同学面试的时候总会被问到有没有遇到过线上 stackOverFlowError ?有么有遇到栈溢出?具体栈溢出怎么来解决?今天他来了,他带着问题走

    2024年01月23日
    浏览(43)
  • 记一次后台开发面试拷打过程

    开头简单的自我介绍,面试官和我聊了聊天缓解个人紧张状况,然后就让开屏幕共享开视频做题目,做完以后,问了一些问题,就让等通知了,估计是凉了,不过这里且把当时做的笔试题目复盘一下吧!题目是ai做的题解,唉,AI都比我强,比我面试的时候解释的强多了,未来

    2024年02月08日
    浏览(42)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包