我写了一个下面显示的小程序,该程序计算无限递归循环在导致StackOverflow错误之前将经过多少次。
let objectsToShare = [textToShare, otherObject] as [Any]
let activityVC = UIActivityViewController(activityItems: objectsToShare, applicationActivities: nil)
//New Excluded Activities Code
activityVC.excludedActivityTypes = [UIActivityType.addToReadingList]
//
activityVC.popoverPresentationController?.sourceView = sender as? UIView
self.present(activityVC, animated: true, completion: nil)
问题是,它每次都会错误编号,通常在8000到9000之间。有人能解释为什么会这样吗?
编辑:我正在使用Eclipse IDE,尚未与其他IDE或命令行对其进行测试。
答案 0 :(得分:7)
JVM规范很好地解释了其与堆栈有关的行为;
每个Java虚拟机线程都有一个专用的Java虚拟机 堆栈,与线程同时创建。 Java虚拟机 堆栈存储帧(第2.6节)。 Java虚拟机堆栈类似于 到常规语言(例如C)的堆栈:它保存本地 变量和部分结果,并在方法调用中起作用 然后返回。因为Java虚拟机堆栈永远不会 除了推和弹出框架外,直接操纵的框架可能是堆的 已分配。 Java虚拟机堆栈的内存不需要 是连续的。
在Java®虚拟机规范的第一版中, Java虚拟机堆栈被称为Java堆栈。
此规范允许Java虚拟机堆栈为 固定大小或根据需要动态扩展和收缩 计算。如果Java虚拟机堆栈的大小固定, 可以选择每个Java虚拟机堆栈的大小 创建该堆栈时独立运行。
Java虚拟机实现可以为程序员或 用户控制Java虚拟机堆栈的初始大小, 以及在动态扩展或收缩Java的情况下 虚拟机堆栈,可控制最大和最小大小。
以下与Java Virtual相关的特殊条件 机器堆栈:
如果线程中的计算需要更大的Java虚拟机 如果堆栈超出了允许的范围,则Java虚拟机将抛出一个 StackOverflowError。
如果Java虚拟机堆栈可以动态扩展,并且 尝试扩展,但可用内存不足 进行扩展,或者如果没有足够的内存 可用于为新的Java虚拟机创建初始堆栈 线程,Java虚拟机将引发OutOfMemoryError。
就您的问题而言,摘录中的重要一点:
由于没有提供堆栈大小,因此JVM尝试动态扩展堆栈大小,因为该函数被递归调用,需要更多的堆栈内存。在每次运行中,它可能会为其堆栈找到不同数量的动态内存,具体取决于运行时计算机上内存的可用性。这就是为什么您在抛出SO错误之前看到的迭代次数值会有所不同的原因。如果(使用Xss<size>
JVM参数)为程序配置较小的堆栈大小,则应该在SO错误之前看到几乎相同数量的递归。
答案 1 :(得分:1)
可能与计算机可以为程序分配多少实际内存有关,而计算机中正在运行其他程序和进程
答案 2 :(得分:1)
StackOverflowError是一个错误。作为错误,与JVM有关(错误不是Exception!)。
当您的堆栈(或方法执行堆栈)与您的堆大小(JVM的内存)冲突时,会发生此错误。
可以定义JVM堆的大小,但是可以从堆栈中定义。
答案 3 :(得分:1)
因此,正如其他人指出的那样,您可能必须查看正在使用的jvm,并从那里了解使用了什么垃圾收集器(多久调用一次gc)也是一个不错的练习,因为这可能会给您不仅对堆栈溢出错误有更深入的了解,而且对Java的工作原理有更深入的了解。如果真的很热衷,您可以实现自己的小型JVM,并且可能会有更好的方案。
答案 4 :(得分:0)
StackOverflowError
。您无法预测何时引发错误,因为除非由-Xss
标志指定,否则堆栈的大小可以是动态的。这就是为什么没有固定的方法执行深度会导致StackOverflowError
的原因。