记录一次递归查询导致的 java.lang.StackOverflowError: null

2024-06-21 02:20

本文主要是介绍记录一次递归查询导致的 java.lang.StackOverflowError: null,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

问题截图:

由于作者使用递归统计信息,刚开始这个接口运行得正常,但是上线运行一段时间后接口就出现了,如图的栈溢出错误。可以看出确实是堆栈溢出了,解决栈溢出目前只有两种方式:

第一种调大栈的大小:

-Xss 来配置栈的大小。 目前作者没有选择个方式。

第二种通过读代码减少递归层数:

public Set<String> getTableParents(Set<String> targetIds,Set<String> parentsSet){List<LineageTableDO> tableDOList = tableRelationMapper.selectList(new LambdaQueryWrapper<LineageTableDO>().in(LineageTableDO::getTargetId,targetIds));if (ObjectUtils.isNotEmpty(tableDOList)){Set<String> newTargetIds = new HashSet<>();//将父系id查出来,tableDOList.stream().forEach(s->newTargetIds.add(s.getSourceId()));parentsSet.addAll(newTargetIds);//再作为字进行二次查询getTableParents(newTargetIds,parentsSet);}return parentsSet;}

作者通过日志和阅读代码逻辑发现,每次newTargetIds 基本都是重复的,导致递归次数指数增长,于是修改成如下代码:

public Set<String> getTableParents(Set<String> targetIds,Set<String> parentsSet){//System.out.println("targetIds Size =========>" + targetIds.size() + ",  pSet==========>" + parentsSet.size());List<LineageTableDO> tableDOList = tableRelationMapper.selectList(new LambdaQueryWrapper<LineageTableDO>().in(LineageTableDO::getTargetId,targetIds));if (ObjectUtils.isNotEmpty(tableDOList)){//System.out.println("childTable size ==========> " + tableDOList.size());Set<String> newTargetIds = new HashSet<>();//将父系id查出来,tableDOList.stream().forEach(s->newTargetIds.add(s.getSourceId()));Set<String> tmpSets = new HashSet<>();if (CollectionUtils.isNotEmpty(newTargetIds)) {newTargetIds.forEach(s -> {if (!parentsSet.contains(s)) {tmpSets.add(s);}});}if (CollectionUtils.isNotEmpty(tmpSets)) {parentsSet.addAll(tmpSets);//再作为字进行二次查询getTableParents(newTargetIds,parentsSet);}}return parentsSet;}

最后成功解决

这篇关于记录一次递归查询导致的 java.lang.StackOverflowError: null的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


原文地址:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.chinasem.cn/article/1079935

相关文章

SpringBoot集成P6Spy的实现示例

《SpringBoot集成P6Spy的实现示例》本文主要介绍了SpringBoot集成P6Spy的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面... 目录本节目标P6Spy简介抛出问题集成P6Spy1. SpringBoot三板斧之加入依赖2. 修改

Linux查询服务器系统版本号的多种方法

《Linux查询服务器系统版本号的多种方法》在Linux系统管理和维护工作中,了解当前操作系统的版本信息是最基础也是最重要的操作之一,系统版本不仅关系到软件兼容性、安全更新策略,还直接影响到故障排查和... 目录一、引言:系统版本查询的重要性二、基础命令解析:cat /etc/Centos-release详

Spring Integration Redis 使用示例详解

《SpringIntegrationRedis使用示例详解》本文给大家介绍SpringIntegrationRedis的配置与使用,涵盖依赖添加、Redis连接设置、分布式锁实现、消息通道配置及... 目录一、依赖配置1.1 Maven 依赖1.2 Gradle 依赖二、Redis 连接配置2.1 配置 R

Spring Security重写AuthenticationManager实现账号密码登录或者手机号码登录

《SpringSecurity重写AuthenticationManager实现账号密码登录或者手机号码登录》本文主要介绍了SpringSecurity重写AuthenticationManage... 目录一、创建自定义认证提供者CustomAuthenticationProvider二、创建认证业务Us

Java Stream流以及常用方法操作实例

《JavaStream流以及常用方法操作实例》Stream是对Java中集合的一种增强方式,使用它可以将集合的处理过程变得更加简洁、高效和易读,:本文主要介绍JavaStream流以及常用方法... 目录一、Stream流是什么?二、stream的操作2.1、stream流创建2.2、stream的使用2.

MySQL慢查询工具的使用小结

《MySQL慢查询工具的使用小结》使用MySQL的慢查询工具可以帮助开发者识别和优化性能不佳的SQL查询,本文就来介绍一下MySQL的慢查询工具,具有一定的参考价值,感兴趣的可以了解一下... 目录一、启用慢查询日志1.1 编辑mysql配置文件1.2 重启MySQL服务二、配置动态参数(可选)三、分析慢查

Java对接MQTT协议的完整实现示例代码

《Java对接MQTT协议的完整实现示例代码》MQTT是一个基于客户端-服务器的消息发布/订阅传输协议,MQTT协议是轻量、简单、开放和易于实现的,这些特点使它适用范围非常广泛,:本文主要介绍Ja... 目录前言前置依赖1. MQTT配置类代码解析1.1 MQTT客户端工厂1.2 MQTT消息订阅适配器1.

Spring Boot项目如何使用外部application.yml配置文件启动JAR包

《SpringBoot项目如何使用外部application.yml配置文件启动JAR包》文章介绍了SpringBoot项目通过指定外部application.yml配置文件启动JAR包的方法,包括... 目录Spring Boot项目中使用外部application.yml配置文件启动JAR包一、基本原理

SpringBoot加载profile全面解析

《SpringBoot加载profile全面解析》SpringBoot的Profile机制通过多配置文件和注解实现环境隔离,支持开发、测试、生产等不同环境的灵活配置切换,无需修改代码,关键点包括配置文... 目录题目详细答案什么是 Profile配置 Profile使用application-{profil

MyBatis流式查询两种实现方式

《MyBatis流式查询两种实现方式》本文详解MyBatis流式查询,通过ResultHandler和Cursor实现边读边处理,避免内存溢出,ResultHandler逐条回调,Cursor支持迭代... 目录MyBATis 流式查询详解:ResultHandler 与 Cursor1. 什么是流式查询?