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


    问题截图:

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

    第一种调大栈的大小:

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

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

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

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

    1. public Set getTableParents(Set targetIds,Set parentsSet){
    2. //System.out.println("targetIds Size =========>" + targetIds.size() + ", pSet==========>" + parentsSet.size());
    3. List tableDOList = tableRelationMapper.selectList(new LambdaQueryWrapper().in(LineageTableDO::getTargetId,targetIds));
    4. if (ObjectUtils.isNotEmpty(tableDOList)){
    5. //System.out.println("childTable size ==========> " + tableDOList.size());
    6. Set newTargetIds = new HashSet<>();
    7. //将父系id查出来,
    8. tableDOList.stream().forEach(s->newTargetIds.add(s.getSourceId()));
    9. Set tmpSets = new HashSet<>();
    10. if (CollectionUtils.isNotEmpty(newTargetIds)) {
    11. newTargetIds.forEach(s -> {
    12. if (!parentsSet.contains(s)) {
    13. tmpSets.add(s);
    14. }
    15. });
    16. }
    17. if (CollectionUtils.isNotEmpty(tmpSets)) {
    18. parentsSet.addAll(tmpSets);
    19. //再作为字进行二次查询
    20. getTableParents(newTargetIds,parentsSet);
    21. }
    22. }
    23. return parentsSet;
    24. }

    最后成功解决

  • 相关阅读:
    1754. 构造字典序最大的合并字符串-交叠比较-力扣双百代码
    670.最大交换 暴力、单调栈、指针的逆序遍历 三种解题思路。
    【已解决】ModuleNotFoundError: No module named sklearn
    数学建模常用模型
    【liunx】yum&&vim
    排序算法复杂度
    基于Google大型分布式系统的网格化实战
    爱上源码,重学Spring MVC深入
    Docker MySql 查看版本的三种方法
    LeetCode-分割回文串(C++)
  • 原文地址:https://blog.csdn.net/u011240463/article/details/139835545