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

Java 进阶:异常影响性能吗?

  • Java 进阶异常影响性能吗
    • catch 中不做任何事情
    • catch 中输出异常到日志
    • catch 中获取异常栈
    • 总结

Java 进阶:异常影响性能吗?

曾经在给一个业务系统增加限流功能,使用的限流组件在流量超过阈值时,会直接抛异常,异常导致 CPU 占用率飙升。第一次遇到这样的情况,让我们不得不思考,异常怎么会对性能造成这么大的影响?

下面我们写几个测试程序观察一下。

catch 中不做任何事情

public class ExceptionTest { public static void main(String[] args) { doExTest(); doExTest(); } private static void doExTest() { long start = System.nanoTime(); for (int i=0; i<100000; ++i) { try { throw new RuntimeException("" + Math.random()); } catch (Exception e) { } } System.out.println("time: " + (System.nanoTime() - start)); } }

测试结果如下:

time: 365218274
time: 224583244

第一次 doExTest 只是起到预热的作用,我们以第二次 doExTest 的时间为准。10 万次请求,平均每次请求耗时 2245 纳秒,也就是 0.002 毫秒,速度还是很快的。

catch 中输出异常到日志

public class ExceptionTest { private static final Logger logger = LoggerFactory.getLogger(ExceptionTest.class); public static void main(String[] args) { doExTest(); doExTest(); } private static void doExTest() { long start = System.nanoTime(); for (int i=0; i<100000; ++i) { try { throw new RuntimeException("" + Math.random()); } catch (Exception e) { logger.error("fuck", e); } } System.out.println("time: " + (System.nanoTime() - start)); } }

测试结果如下:

time: 13454674590
time: 9891780450

10 万次请求,平均每次请求耗时 98917 纳秒,大约 0.1 毫秒,比“不输出异常”的时候,慢了 50 倍。输出日志如此耗费性能,那么 logger.error 这一句做了什么事儿呢?
1. 根据过滤规则,判断是否要输出日志
2. 获取异常堆栈
3. 拼接日志字符串,输出日志到文件

获取异常堆栈主要调用的如下方法,下面我们写程序,不输出日志到文件,测试只读取异常栈的性能:

public class Throwable implements Serializable { public StackTraceElement[] getStackTrace() { return getOurStackTrace().clone(); } private synchronized StackTraceElement[] getOurStackTrace() { // Initialize stack trace field with information from // backtrace if this is the first call to this method if (stackTrace == UNASSIGNED_STACK || (stackTrace == null && backtrace != null) /* Out of protocol state */) { int depth = getStackTraceDepth(); stackTrace = new StackTraceElement[depth]; for (int i=0; i < depth; i++) stackTrace[i] = getStackTraceElement(i); } else if (stackTrace == null) { return UNASSIGNED_STACK; } return stackTrace; } }

catch 中获取异常栈

public class ExceptionTest { public static void main(String[] args) { doExTest(); doExTest(); } private static void doExTest() { long start = System.nanoTime(); for (int i=0; i<100000; ++i) { try { throw new RuntimeException("" + Math.random()); } catch (Exception e) { StackTraceElement[] stackTrace = e.getStackTrace(); } } System.out.println("time: " + (System.nanoTime() - start)); } }

测试结果如下:

time: 1559107012
time: 795376775

10 万次请求,平均每次请求耗时 7953 纳秒,大约 0.008 毫秒,比“不输出异常”的时候,慢了 4 倍。这么看获取堆栈耗时并不多,耗时主要在输出日志到文件中。

总结

处理异常的几个步骤里,对性能的耗费从大到小依次为:输出到日志、获取异常堆栈、创建并 catch 异常。

http://www.jsqmd.com/news/212032/

相关文章:

  • 【Qt改变虚拟键盘的大小】
  • 一个在使用方法上的低级错误(MySQL场景)
  • java学习进阶之路,如果从一个菜鸟进阶成大神
  • java头歌-数组进阶
  • 破解空间困局:看紧凑型ARM工控机如何一机多能
  • java进阶知识点
  • Java基础进阶-水仙花数
  • Java进阶教程(二)代码块
  • 提升Python AI模型训练速度:从入门到进阶的实战优化方案
  • 【论文精读】-Graph-Grounded Pre-training and Prompting
  • Java_ElasticSearch(ES)——分布式搜索引擎
  • 手写一个单例模式 (考虑线程安全)。
  • 深度学习毕设选题推荐:基于python的CNN训练识别吃的美食基于深度学习的CNN训练识别吃的美食
  • 深度学习毕设项目推荐-深度学习基于python的CNN训练识别吃的美食基于python的深度学习CNN训练识别吃的美食
  • 救命神器!9个AI论文网站测评:本科生毕业论文全攻略
  • ReadView的结构和工作原理?
  • Java 进阶:如何让线程主动让出 CPU
  • 亲测好用10个AI论文工具,专科生轻松搞定论文写作!
  • JavaScript 调试
  • AngularJS 模块详解
  • 救命神器!自考必看TOP9 AI论文网站测评与推荐
  • idea创建springBoot的五种方式
  • 毫米波V2I网络的链路层仿真研究(Matlab代码实现)
  • Java实战:Spring Boot application.yml配置文件详解
  • python_flask求职招聘岗位信息分析系统的设计与实现_xz0yin70可视化大屏
  • Prompt Tuning动态选医疗特征提速诊断
  • idea、mybatis报错Property ‘sqlSessionFactory‘ or ‘sqlSessionTemplate‘ are required
  • Azure GPv1 存储账户迁移至 GPv2 完整指南
  • Java学习进阶知识篇
  • Memcached 连接:深入理解与优化实践