【问题标题】:When is it ok to increase the max stack size of the jvm (-Xss)?什么时候可以增加 jvm (-Xss) 的最大堆栈大小?
【发布时间】:2019-12-23 02:22:45
【问题描述】:

我在做什么?

我在 coursera 上做一门课程,这需要我编写一个计算树高的程序。输入是一个父数组,其中每个索引是节点,其值是节点的父节点。如果节点是根节点,其值为-1。

到目前为止我做了什么?

我编写了一个算法,该算法通过递归遍历其子节点直到其根节点并将中间子节点的高度保存在数组(深度变量)中来检查树的高度。因为它是recursion,所以我经常看到stackoverflow exception,这是很自然的,因为堆栈大小不足以容纳大树。

为了摆脱这个异常,我尝试为我的递归调用找到最佳值,结果发现它接近 3100k。此外,当我看到针对一些预定义测试用例测试我的算法的代码时,也将 堆栈大小为 1 传递到线程构造函数中。

我需要知道什么?

  1. 有没有更好的方法来解决这个问题?

  2. 这样增加堆栈大小可以吗?

这是代码

int computeHeight() {
    int[] depth = new int[n];
    int maxHeight = 0;
    for (int i = 0; i < n; i++) {
        int height = computeHeight(parent, depth, i);
        maxHeight = Math.max(height, maxHeight);
    }
    return maxHeight;
}

private int computeHeight(int[] parent, int[] depth, int idx) {
    if (parent[idx] == -1) {
        // root found
        depth[idx] = 1;
        return depth[idx];
    }
    // depth of parent unknown
    if (depth[parent[idx]] == 0) {
        computeHeight(parent, depth, parent[idx]);
    }
    depth[idx] = depth[parent[idx]] + 1;
    return depth[idx];
}

【问题讨论】:

  • 链接给出404
  • 看起来很奇怪,您需要超过 3.1M 的堆栈帧。如果你正确地实现了这个,这应该只发生在深度超过 3.1M 的树上。
  • 如果你可以递归地做到这一点,我相信有一种迭代的方式。除非绝对必要,否则并不总是建议增加堆栈大小。
  • 请按照您创建此帐户时的建议阅读并遵循帮助文档中的发布指南。 Minimal, complete, verifiable example 适用于此。在您发布 MCVE 代码并准确说明问题之前,我们无法有效地帮助您。我们应该能够将您发布的代码粘贴到文本文件中并重现您指定的问题。不接受站外链接。
  • 我很抱歉这个链接。我忘记将回购更改为公开。我会做的。

标签: java algorithm recursion


【解决方案1】:

在现实生活中,只有当你知道深度被限制在一个很小的值时,你才应该使用递归。

例如,递归测量平衡的树很好,但递归测量不平衡的树则不行。

【讨论】:

  • 现在请看一下代码链接。它现在可以工作了。
【解决方案2】:

如果树向右或向左倾斜,例如如果每个节点只有一个右子节点,那么递归很容易导致堆栈溢出(再次取决于堆栈设置),不确定其中一个输入是否适合您的情况。

这可以以迭代方式完成:

a) 将所有父项(数组中的值)添加到 HashSet

b) 然后遍历所有节点(这里只是从 0 到 n 的索引)并查看它是否存在于集合中,如果不是它是叶子。

c) 然后从叶子遍历到根来获取高度,同时将每个节点的高度存储在一个数组中,这样下次你就不必再爬上相同的路径了。

d) 每次更新最大高度。

【讨论】:

  • 如果可以的话,请看一下代码。该链接现在有效
【解决方案3】:

您遇到堆栈溢出错误似乎很奇怪,我假设这是一个如此简单的问题;当它是一棵非常大的树或由于某种原因在它期间加载大量 RAM 时,这只会成为递归问题。我建议您发布您的代码。

至于增加堆栈大小,这不是问题,因为您只是在做练习题。然而,在现实世界中,这可能会带来挑战,并且是使用递归的风险之一。如果您在各种设备上使用您的应用程序,由于设备的限制,增加堆栈大小可能并不总是可行的。相反,我建议您尽可能避免使用递归,除非您知道要递归的树足够小而不会导致溢出。

如需替代解决方案,请尝试here

【讨论】:

    猜你喜欢
    • 2015-12-11
    • 2013-01-01
    • 1970-01-01
    • 2011-08-26
    • 2015-11-22
    • 2010-11-29
    • 1970-01-01
    相关资源
    最近更新 更多