当前位置: 首页 > news >正文

记一次 stackoverflowerror 线上排查过程

一.线上 stackOverFlowError

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

二.优先线上问题解决

请原谅我抽象的画风

    temp 方案.首先的线上的稳定性肯定是第一要义,客户可不会等你长篇大论抓包,分析,debug.过了30min还不恢复,资本的大刀就要砍到你身上了.所以我们先想到的是代码回退,镜像回滚解决问题优先.虽然说是临时方案,那这时候我觉得这可能是最重要的最佳方案.毕竟老镜像是不会出任何问题的.

三.继续深入分析

    解决完线上的问题后,先从外层的堆栈打印来看,找到 ClassCastException 这里找到真实的原因,毕竟退下来的不仅仅是坏代码,还有需求迭代的正常需求还是需要继续推上去上线.

3.1 整体的流程梳理

    找到报错第一步:

3.1.1 step1: classCastException

    先表象开始分析

从这里可以看到判断了是否为 Throwable 类型.如果是就进行 Exception 强转.这里就要复习一下了.

StackOverFlowError 继承 Error ,ErrorThrowable 继承而来. Exception 则是另外的分支. 对于 ErrorException 也有通行的原则. Exception 一般是程序中用以来抛出程序异常所使用的且一般是能够通过编码优化来解决的,或是用来 try catch exception 来进行捕获处理的. Error 则是用来表达程序运行期间出现的严重错误,这时候通常是jvm级别的.如常见的OutOfMemoryError,stackOverFlowError.等.通常则是无法通过代码来进行捕获的.

    有了这些基础知识后,再回来这里虽然StackOverFlowErrorException都继承于 Throwable .但这是两个子的实现,没法做到强转.由之得到了 ClassCastException .后面这就是转成了 ClassCastException .这个类则是继承自 Exception .通过 try catch 捕获异常后,得到了正常的日志打印,也就是收到的日志告警. 然后这仅仅是表现.根因还没有找到.

    当然这段代码也需要进行优化.如果得到的是Error的类型就要对应的进行Error的处理而不是仅仅对Throwable都统一强转为Exception
代码优化

 Exception exception = null;f(ar instanceof Error){Error arError=(Error)ar; exception=new Exception (arError);}else if(ar instanceof Exception){exception = (Exception) ar;}

3.1.2 step2:事情远没有结束,到底是哪里出问题 StackOverFlowError

    本质上还是由于StackOverFlowError才得到的如上的 ClassCastException. 回忆下 JVM 的内存布局(如下图)

    能发生 StackOverFlowError 只有在线程私有的 stack(native method stack | virtual method stack) 这里.这里通常发生这个错误的原因是因为方法调度的深度过长了或是线程本身分别的内存太小不足以支持现在的复杂调用.

  • 第一种场景:常见的如递归调用.
  • 第二种场景: jvm 在1.5 之后默认的xss 大小默认为 1m.一般场景下支持1000-2000个深度调用没问题.包括递归.(没试过.数值参考自:深入理解java虚拟机)

3.1.3 找到问题对比代码

    从一般情况下第二种场景不太可能出现.还是回到递归调用引起的.排查代码.花不多少,看代码,通过对比版本之间diff(对比时间稍微有点长).简略如下:

无问题代码

private static void error(Logger logger, String message, Object... arg) {if (isLogOn(LogLevelEnum.ERROR, logger)) {if (arg != null && arg.length > 0 && arg[0] instanceof Throwable) {logger.error(message, arg[0]);} else {logger.error(message, arg);}TRACER_LOGGER.error(message, arg);}}
public static void error(Object... arg) {String message = getMessage("{}", 4, arg);error(getSoaErrorLogger(), message, arg);}public static void error(String message, Object... arg) {message = getMessage(message, 4, arg);error(getSoaErrorLogger(), message, arg);}

代码优化后的代码 有问题版

private static void error(Logger logger,String realMessage, String message, Object... arg) {if (isLogOn(LogLevelEnum.ERROR, logger)) {if (arg != null && arg.length > 0 && arg[0] instanceof Throwable) {logger.error(message, arg[0]);} else {logger.error(message, arg);}TRACER_LOGGER.error(message, arg);}}
public static void error(Object... arg) {String message = getMessage("{}", 4, arg);error(getSoaErrorLogger(), message, arg);}public static void error(String message, Object... arg) {message = getMessage(message, 4, arg);final String realMessage=message;error(getSoaErrorLogger(),realMessage, message, arg);}

代码优化后的代码 完善版

private static void error(Logger logger,String realMessage, String message, Object... arg) {if (isLogOn(LogLevelEnum.ERROR, logger)) {if (arg != null && arg.length > 0 && arg[0] instanceof Throwable) {logger.error(message, arg[0]);} else {logger.error(message, arg);}TRACER_LOGGER.error(message, arg);}}
public static void error(Object... arg) {String message = getMessage("{}", 4, arg);final String realMessage=message;error(getSoaErrorLogger(),realMessage, message, arg);}public static void error(String message, Object... arg) {final String realMessage=message;message = getMessage(message, 4, arg);        error(getSoaErrorLogger(),realMessage, message, arg);}

    咋一看没有任何问题.但是上线后出现第二个方法递归调用自身(但是第二个方法没有变更内容哈).本质上的原因就是因为修改第一个方法增加了入参.但是仅修改了第三个方法,第二个方法没有修改.没有出现编译问题.因为本身第二个方法是一个Object… arg的数组调用.好坑.

四.总结

  • 区别ErrorException.系统最外层建议捕获所有异常,也就是Throwable,但是具体是Error,还是Exception要进行区分处理.
  • 尽量不使用,少使用数组式使用.如String… args.Integer… args .即使要用,也尽量不要用Object… args .避免调用错误.
  • 在做技术优化时,尽可能评估影响,对线上抱有充分的敬畏.慎之又慎.如没有特别的收益,可不上线.上线也要保证每一行改动与本次受影响的代码做到测试
  • 修改代码找到所有find usage ,避免出现错改,漏改.可以利用自带IDE的工具 做到.

赠人玫瑰 手有余香,我是柏修
求关注、求点赞,加个关注不迷路,感谢
点赞是对我最大的鼓励
↓↓↓↓↓↓

相关文章:

记一次 stackoverflowerror 线上排查过程

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

论文写作之十个问题

前言 最近进入瓶颈? 改论文,改到有些抑郁了 总是不对,总是被打回 好的写作,让人一看就清楚明白非常重要 郁闷时候看看大佬们怎么说的 沈向洋、华刚:读科研论文的三个层次、四个阶段与十个问题 十问 What is the pro…...

leetcode2171 拿出最少数目的魔法豆

题目 给定一个 正整数 数组 beans ,其中每个整数表示一个袋子里装的魔法豆的数目。 请你从每个袋子中 拿出 一些豆子(也可以 不拿出),使得剩下的 非空 袋子中(即 至少还有一颗 魔法豆的袋子)魔法豆的数目…...

测试C#调用OpenCvSharp和ViewFaceCore从摄像头中识别人脸

学习了基于OpenCvSharp获取摄像头数据,同时学习了基于ViewFaceCore的人脸识别用法,将这两者结合即是从摄像头中识别人脸。本文测试测试C#调用OpenCvSharp和ViewFaceCore从摄像头中识别人脸,并进行人脸红框标记。   新建Winform项目&#xf…...

测试经理面试初体验

家人们谁懂啊,我在海口实在难找计算机类的实习,就直接在BOss上海投了,结果一个hr直接给我弄了个测试经理的面试(可能年底冲业绩吧),然后就在明天下午,我直接抱下f脚了,就当体验一下~…...

使用ffmpeg调整视频中音频采样率及声道

1 原始视频信息 通过ffmpeg -i命令查看视频基本信息 ffmpeg -i example2.mp4 ffmpeg version 6.1-essentials_build-www.gyan.dev Copyright (c) 2000-2023 the FFmpeg developersbuilt with gcc 12.2.0 (Rev10, Built by MSYS2 project)configuration: --enable-gpl --enable…...

详细分析Java中的Date类以及格式转换

目录 前言1. 基本知识2. 格式化输出3. 格式转换 前言 记录这篇文章的缘由,主要是涉及一个格式转换,对此深挖了这个类 在Java中,Date类是用于表示日期和时间的类。 位于java.util包中,是Java平台中处理日期和时间的基本类之一。…...

【计算机网络】应用层——HTTP 协议(一)

个人主页:兜里有颗棉花糖 欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 兜里有颗棉花糖 原创 收录于专栏【网络编程】 本专栏旨在分享学习计算机网络的一点学习心得,欢迎大家在评论区交流讨论💌 目录 一、什么是 HTTP 协…...

线程和进程的区别

Java面试题 线程和进程的区别 进程是操作系统资源分配的基本单位。 线程是处理器任务调度和执行的基本单位 一个进程可以包含多个线程。进程之间的资源是相互独立,而同一进程下的线程之间可以共享进程中的资源。...

proxy 代理的接口报错301问题

项目系统里仅仅这个接口报错,反向代理错误导致。 默认情况下,不接受运行在HTTPS上,且使用了无效证书的后端服务器。如果你想要接受,修改配置:secure: false(简单意思:如果本地没有进行过https相…...

mysql进阶-执行计划

目录 1. 概念 2. 使用 3. 具体相关字段含义 3.1 id 3.2 select_type 3.3 table 3.4 partition 3.5 type 3.6 possible_key 3.7 key 3.8 key_len 3.9 ref 3.10 row 3.11 filtered 3.12 extra 1. 概念 一条语句通过优化器之后,会生成具体的执行计划用…...

【UE5】第一次尝试项目转插件(Plugin)的时候,无法编译

VS显示100条左右的错误,UE热编译也不能通过。原因可能是[名字.Build.cs]文件的错误,缺少一些内容,比如说如果要写UserWidget类,那么就要在 ]名字.Build.cs] 中加入如下内容: public class beibaoxitong : ModuleRules …...

MeterSphere本地化部署实践

项目结构 搭建本地环境 安装JDK11,配置好JDK环境,系统同时支持JDK8和JDK11安装IEAD,配置JDK环境配置maven环境,IDEA配置(解压可以直接使用)无限重置IDEA试用期配置redis环境(解压可以直接使用) 配置kafka环境 安装mysql-5.7环境&#xff…...

巨变!如何理解中国发起的“数据要素X”计划?

作者 张群(赛联区块链教育首席讲师,工信部赛迪特聘资深专家,CSDN认证业界专家,微软认证专家,多家企业区块链产品顾问)关注张群,为您提供一站式区块链技术和方案咨询。 刘烈宏在第25届北大光华新…...

CS8370错误,这是由于使用了C# 7.3中不支持的功能

目录 背景: 第一种方法: 第二种办法: 背景: 在敲代码的时候,程序提示报错消息提示:CS8370错误,那么这是什么原因导致的,这是由于使用了C# 7.3中不支持的功能,不支持该功能,那就是版本太低我们就需要升级更高的版本&…...

Raspbian安装云台

Raspbian安装云台 1. 源由2. 选型3. 组装4. 调试4.1 python3-print问题4.2 python函数入参类型错误4.3 缺少mjpg-streamer可执行文件4.4 缺失编译头文件和库4.5 python库缺失4.6 图像无法显示,但libcamera-jpeg测试正常4.7 异常IOCTL报错4.8 Git问题 5. 效果5.1 WEB…...

蓝桥杯理历年真题 —— 数学

1. 买不到的数目 这道题目,考得就是一个日常数学的积累,如果你学过这个公式的话,就是一道非常简单的输出问题;可是如果没学过,就非常吃亏,在考场上只能暴力求解,或是寻找规律。这就要求我们什么…...

自然语言处理--双向匹配算法

自然语言处理作业1--双向匹配算法 一、概述 双向匹配算法是一种用于自然语言处理的算法,用于确定两个文本之间的相似度或匹配程度。该算法通常使用在文本对齐、翻译、语义匹配等任务中。 在双向匹配算法中,首先将两个文本分别进行处理,然后…...

IDEA 2023.3.2 安装教程

1.下载2023.3.2版本IDEA 链接:https://pan.baidu.com/s/1RkXBLz6qxsd8VxXuvXCEMA?pwd5im6 提取码:5im6 2.安装 3.解压文件,进入,选择方式3 4.将下面文件夹复制到任意位置(不要有中文路径) 5.进入下面文…...

C语言常见面试题:什么是宏,宏的作用是什么?

宏在计算机科学中是一种批量处理程序命令,它是一种抽象的规则或模式,用于说明某一特定输入(通常是字符串)如何根据预定义的规则转换成对应的输出(通常也是字符串)。在编译时,预处理器会对宏进行…...

大数据学习栈记——Neo4j的安装与使用

本文介绍图数据库Neofj的安装与使用,操作系统:Ubuntu24.04,Neofj版本:2025.04.0。 Apt安装 Neofj可以进行官网安装:Neo4j Deployment Center - Graph Database & Analytics 我这里安装是添加软件源的方法 最新版…...

手游刚开服就被攻击怎么办?如何防御DDoS?

开服初期是手游最脆弱的阶段,极易成为DDoS攻击的目标。一旦遭遇攻击,可能导致服务器瘫痪、玩家流失,甚至造成巨大经济损失。本文为开发者提供一套简洁有效的应急与防御方案,帮助快速应对并构建长期防护体系。 一、遭遇攻击的紧急应…...

云计算——弹性云计算器(ECS)

弹性云服务器:ECS 概述 云计算重构了ICT系统,云计算平台厂商推出使得厂家能够主要关注应用管理而非平台管理的云平台,包含如下主要概念。 ECS(Elastic Cloud Server):即弹性云服务器,是云计算…...

JavaScript 中的 ES|QL:利用 Apache Arrow 工具

作者:来自 Elastic Jeffrey Rengifo 学习如何将 ES|QL 与 JavaScript 的 Apache Arrow 客户端工具一起使用。 想获得 Elastic 认证吗?了解下一期 Elasticsearch Engineer 培训的时间吧! Elasticsearch 拥有众多新功能,助你为自己…...

全球首个30米分辨率湿地数据集(2000—2022)

数据简介 今天我们分享的数据是全球30米分辨率湿地数据集,包含8种湿地亚类,该数据以0.5X0.5的瓦片存储,我们整理了所有属于中国的瓦片名称与其对应省份,方便大家研究使用。 该数据集作为全球首个30米分辨率、覆盖2000–2022年时间…...

376. Wiggle Subsequence

376. Wiggle Subsequence 代码 class Solution { public:int wiggleMaxLength(vector<int>& nums) {int n nums.size();int res 1;int prediff 0;int curdiff 0;for(int i 0;i < n-1;i){curdiff nums[i1] - nums[i];if( (prediff > 0 && curdif…...

SpringBoot+uniapp 的 Champion 俱乐部微信小程序设计与实现,论文初版实现

摘要 本论文旨在设计并实现基于 SpringBoot 和 uniapp 的 Champion 俱乐部微信小程序&#xff0c;以满足俱乐部线上活动推广、会员管理、社交互动等需求。通过 SpringBoot 搭建后端服务&#xff0c;提供稳定高效的数据处理与业务逻辑支持&#xff1b;利用 uniapp 实现跨平台前…...

BCS 2025|百度副总裁陈洋:智能体在安全领域的应用实践

6月5日&#xff0c;2025全球数字经济大会数字安全主论坛暨北京网络安全大会在国家会议中心隆重开幕。百度副总裁陈洋受邀出席&#xff0c;并作《智能体在安全领域的应用实践》主题演讲&#xff0c;分享了在智能体在安全领域的突破性实践。他指出&#xff0c;百度通过将安全能力…...

3403. 从盒子中找出字典序最大的字符串 I

3403. 从盒子中找出字典序最大的字符串 I 题目链接&#xff1a;3403. 从盒子中找出字典序最大的字符串 I 代码如下&#xff1a; class Solution { public:string answerString(string word, int numFriends) {if (numFriends 1) {return word;}string res;for (int i 0;i &…...

在web-view 加载的本地及远程HTML中调用uniapp的API及网页和vue页面是如何通讯的?

uni-app 中 Web-view 与 Vue 页面的通讯机制详解 一、Web-view 简介 Web-view 是 uni-app 提供的一个重要组件&#xff0c;用于在原生应用中加载 HTML 页面&#xff1a; 支持加载本地 HTML 文件支持加载远程 HTML 页面实现 Web 与原生的双向通讯可用于嵌入第三方网页或 H5 应…...