***Error - 堆栈大小和递归
Posted
技术标签:
【中文标题】***Error - 堆栈大小和递归【英文标题】:***Error - Stack Size & Recursion 【发布时间】:2021-12-15 15:29:17 【问题描述】:我认为我关于 Stack Overflow 的第一个问题应该是关于堆栈溢出错误......
我使用递归算法解决了 Code Wars 中的“观察到的 PIN”问题:
https://www.codewars.com/kata/5263c6999e0f40dee200059d
import java.util.List;
import java.util.ArrayList;
public class ObservedPin
static StringBuilder sb = new StringBuilder();
static int[] digits;
static int[] index;
static List<String> perms = new ArrayList<String>();
static int[][] nums = 0, 8, 1, 2, 4, 1, 2, 3, 5, 2, 3, 6,
1, 4, 5, 7, 2, 4, 5, 6, 8, 3, 5, 6, 9, 4, 7, 8,
5, 7, 8, 9, 0, 6, 8, 9;
public static List<String> getPINs(String observed)
digits = new int[observed.length()];
index = new int[observed.length()];
for (int i = 0; i < digits.length; i++)
digits[i] = observed.charAt(i) - 48;
permutations(0);
return perms;
public static void permutations(int level)
if (index[level] == nums[digits[level]].length)
if (level == 0)
return;
else
index[level] = 0;
index[level - 1]++;
level = 0;
else
if (level == digits.length - 1)
//addPinToList(); **** commented out to see if this affected the required memory ****
index[level]++;
else
level++;
permutations(level);
public static void addPinToList()
for (int i = 0; i < digits.length; i++)
sb.append(Integer.toString(nums[digits[i]][index[i]]));
perms.add(sb.toString());
sb.setLength(0);
在看到其他“最佳实践”和“聪明”的解决方案后,我意识到这绝对不是要走的路,我应该以不同的方式解决问题。无论如何,在测试我的解决方案时,我将一个具有最高可能排列数的 PIN 号传递给了 getPINs 方法。任何完全由 5 和 8 组成的 PIN 将产生 320,625 种可能的排列。我使用了 PIN 58585858。 当我运行代码时,我得到了 ***Error。我对代码进行了一些我认为可能会有所帮助的更改,但没有任何效果。最终我增加了堆栈大小并且代码运行良好。只是出于兴趣,我注释掉了将排列添加到“perms”列表的行,认为这也会减少所需的内存,但是当使用默认的 1Mb 堆栈大小时,我得到了同样的错误。 如果递归方法不创建任何参数或对象,或者对任何现有参数/对象的大小有任何影响,为什么它会占用这么多内存? JVM 是否为每次递归创建一个新的堆栈帧,所以是这些帧占用了内存?
我正在自学,我对此很陌生,您可能已经猜到了。
【问题讨论】:
【参考方案1】:JVM 是否为每个递归创建一个新的堆栈帧,所以它是 占用内存的帧?
是的。堆栈帧是您需要能够建立执行上下文(也称为“激活记录”)并返回的内容。它至少包含一个返回地址。一般来说,它可能还包含保存的寄存器和例程参数。
Link - stack frame description for JVM
【讨论】:
很高兴知道。感谢那。以后我可能会更加谨慎地使用递归!以上是关于***Error - 堆栈大小和递归的主要内容,如果未能解决你的问题,请参考以下文章
为啥 malloc() 和普通数组声明分配的堆栈帧大小不同?