【问题标题】:When does StackOverflowError get thrown?StackOverflowError 什么时候被抛出?
【发布时间】:2017-04-22 12:42:56
【问题描述】:

在作业中出现的一些问题,可能是由于我的土豆笔记本电脑造成的,但我感兴趣的是 StackOverflow 何时会因 BST 不平衡而发生(故意)。

所以我比较了搜索 AVL 树与不平衡 BST 的最差性能,搜索元素的相同方法适用于 AVL,但 BST 出现 StackOverflow 错误。 BST 最终只是一个链接列表,其中输入了“坏数据”(字母名称;大约 10000),那么在多少次调用 entryExists 时会产生该错误?

我知道不平衡 BST 在最坏情况下的性能显然比 AVL 差得多,但我想限制搜索查询以获取某种时间数。

[我不认为发布实际代码是必要的,但如果有人需要它,我会上传它——据我所知,不只是我在做无限递归(两者使用相同的方法)。 ]

【问题讨论】:

  • 当您的代码不断调用自己时,它会被抛出,例如当一个方法再次调用自己时。您很可能在代码正在执行的某些递归中弄乱了返回条件。
  • 这里,在这个网站上,stackoverflow 异常以downvotes 的形式出现,因为人们认为你之前没有做过任何研究,例如在搜索引擎中输入异常名称
  • 没错@StephenC,我的错!但不幸的是,我现在无法编辑它。所以我再次删除并重新发布评论。感谢您纠正我。
  • StackOverflowError 是由于您的程序中发生了无数次方法调用而导致的情况。无限是指超过方法调用堆栈的允许大小。这种情况主要发生在您以递归方式实现算法并且未正确实现初始条件以停止自调用时。如果您正确实现了算法,则可以增加堆栈大小以支持所需的递归调用数量。在这里您可以找到方法:stackoverflow.com/questions/3700459/…

标签: java binary-search-tree avl-tree


【解决方案1】:

堆栈溢出发生在单个线程上有太多方法调用活动(即正在进行中)的情况。

每个方法调用都需要一个堆栈框架来保存调用的局部变量,以及一些调用内务信息。 (通常是返回地址和保存的栈顶指针。)线程的堆栈帧保存在线程的堆栈中。这具有固定大小(在创建线程时确定)。默认值取决于 JVM 和命令行开关,但通常为 1Mbytes。

有四种情况会导致堆栈溢出:

  1. 保证无限递归会导致堆栈溢出(除非其他东西首先终止代码)。
  2. 太深的有限递归。例如,如果您的代码递归地遍历列表,它很可能会溢出堆栈,因为列表足够长。 (递归不是无限的。)
  3. 非递归代码复杂且涉及非常深的调用堆栈。
  4. 具有调用链的非递归代码涉及具有大量局部变量的方法。

场景 3 和 4 不太可能,但如果您的线程是使用异常小的线程堆栈创建的,则它们更有可能发生。 (例如,如果您想节省线程堆栈内存。)


就您而言,情况 2 是您的担忧。如果您的树正确平衡,则不会发生这种情况。但是,如果一棵树非常不平衡,它可能会非常深。将其与递归(例如)搜索树的算法相结合,足够深的树会导致堆栈溢出。

注意:这不是无限递归。相反,它是递归算法和具有不幸“形状”的数据结构的组合。

【讨论】:

    猜你喜欢
    • 2011-03-22
    • 2011-11-10
    • 1970-01-01
    • 2020-02-24
    • 2014-01-06
    • 2011-10-27
    • 2021-09-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多