java - java中的内存不足错误

标签 java out-of-memory heap-memory

我收到 OutOfMemoryError: java heap

方法的片段:

{
// step 1: I am creating a 2 dim array
  int totalCombination = (int) Math.pow(2.0, (double) vowelCount);
// here vowelCount > 10

// step2: initializing my array
// step3: and using that array
}

我的问题:

每次调用此方法时,都会创建该数组。 有没有可能阵列没有被释放。

在 Windows taskmanager 中,我可以看到 java 使用的内存是纯粹增量的。 因此,并不是堆大小在某一点上变小了,而是内存被重复使用而没有以某种方式释放。

如果您需要更多详细信息,请告诉我。

请帮忙调试错误

阿努杰

可能导致错误的代码部分:

int totalCombination = (int) Math.pow(2.0, (double) vowelCount);

    int lookupArray[][] = new int[totalCombination][vowelCount];

    // initialize lookupArray

    for (int i = 0; i < totalCombination; i++) {
        for (int j = 0; j < vowelCount; j++) {
            lookupArray[i][j] = 0;
        }
    }

    // populate lookupArray
    //vowelCount : number of vowels in a word
    // if count is 2, then array will contain 00,01,10,11

    for (int i = 1; i < totalCombination; i++) {
        for (int c = 0; c < vowelCount; c++) {
            lookupArray[i][c] = lookupArray[i - 1][c];
        }
        boolean flag = true;
        for (int j = vowelCount - 1; j >= 0 && flag; j--) {
            if (lookupArray[i - 1][j] == 1) {
                lookupArray[i][j] = 0;
            } else if (lookupArray[i - 1][j] == 0) {
                lookupArray[i][j] = 1;
                flag = false;
            }
        }
    }


  // this part total combination of a word having different combination of vowels in it.


    for (int i = 0; i < totalCombination; i++) {
        int vcount = vowelCount - 1;
        StringBuffer stringBuffer = new StringBuffer();

        for (int j = 0; j < word.length(); j++) {
            if (wordArr[j] == 'a' || wordArr[j] == 'e' || wordArr[j] == 'i'
                    || wordArr[j] == 'o' || wordArr[j] == 'u') {
                if (lookupArray[i][vcount] == 1) {
                    stringBuffer.append(wordArr[j]);
                }
                vcount--;
            } else {
                stringBuffer.append(wordArr[j]);
            }
        }

最佳答案

2 的幂呈指数增长。如果 vowelCount 很高,单独一个数组很容易导致 OutOfMemoryError (2^32 = 4GB)。

您可以尝试调整您的 VM 最大内存要求(例如 -Xmx512m),但要意识到您的算法需要大量内存。如果可能的话,您可能希望找到更好的算法。


另见


编辑后:正如我所料,您正在生成一个充满所有二进制可能性的巨大数组。您很少需要将整个数组实际存储在内存中。您可以“即时”生成每个可能的组合,并将其“即时”提供给需要 0 和 1 的任何人。

请记住,这仍然是指数级增长,因此即使您已经处理了从 O(2^N)O(N)< 的内存需求,你的时间复杂度仍然是O(2^N)

each time this method is called, that array is getting created. Is it possible that the array is not getting released .

是的,这是很有可能的,如果对数组的引用曾被泄露,然后某个地方的某些东西保留了这个引用。垃圾收集器并不真正关心认为什么是/不是垃圾;只要某个对象被某物引用(并且它不是弱引用等),它就不是垃圾。


在弄清楚您要做什么之后,这是我的解决方案。请注意,它根本不会生成位数组。

static void generate(String prefix, String suffix) {
    int i = suffix.replaceAll("[aeiou].*", "").length();
    if (i == suffix.length()) {
        System.out.println(prefix + suffix);
    } else {
        generate(prefix + suffix.substring(0, i), suffix.substring(i + 1));
        generate(prefix + suffix.substring(0, i+1), suffix.substring(i + 1));
    }
}

// generate("", "apple");

它使用正则表达式查找下一个元音的位置。您可以改用常规的 for 循环,通用算法仍然有效。您可以优化它以使用 StringBuilder 代替(我主要是为了简明扼要,希望这段代码清晰)。


这里有一个替代解决方案,它使用 split 将输入字符串预切成片段(O(N) 空间),然后使用 StringBuilder 生成所有其他字符串(O(N) 空间)。

static void generate(StringBuilder sb, String[] parts, int i) {
    if (i == parts.length) {
        System.out.println(sb.toString());
    } else {
        if ("aeiou".contains(parts[i])) {
            generate(sb, parts, i + 1);
        }
        sb.append(parts[i]);
        generate(sb, parts, i + 1);
        sb.setLength(sb.length() - parts[i].length());
    }
}
static void generate(String s) {
    generate(
        new StringBuilder(),
        s.split("(?<=[aeiou])|(?=(?!^)[aeiou])"),
        0
    );
}

// generate("apple");

正则表达式将 "apple" 拆分为 [ "a", "ppl", "e"]。它在元音后到处分开,或者(如果它不是字符串的开头)在元音前到处分开。

现在应该很明显,空间要求是 O(N),所以除非您的字符串长得离谱,否则这不应该导致 OutOfMemoryError.

当然,如果您存储生成的字符串——它们的所有O(2^N)——在内存中,那么当然 你会得到 OutOfMemoryError。我希望这个事实是显而易见的。

整个想法 是不在内存中存储您不需要生成此巨大输出的任何内容。如果您随后将所有这些巨大的输出存储在内存中(而不是将它们打印到 stdout 或文件),那么它会破坏整个目的,您将得到一个 OutOfMemoryError 符合预期

关于java - java中的内存不足错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2657525/

相关文章:

Java EDT 和生成对话

java - 如何使用方法修复 "actual and formal argument lists differ in length"?

C++:删除结构?

winapi - 我如何告诉 MS CRT 在 Windows XP 上使用低碎片堆?

java - 将 RMI 限制到一个端口的含义

java - 在 Java 中向 UI 显示控制台输出

java - Tomcat 8.5 Wildfly 15 Java 8 OutOfMemoryError 和启动速度非常慢

c - 哪个更好, ch = '\n' ;写(1,&ch,1);或 putchar ('\n' );?

java - 即使没有内存不足,我也会遇到 java.lang.OutOfMemoryError 吗?

java - 在物理内存为 16 GB RAM 和 8 个 CPU 的 Linux 上,JDK8 64 位的 JVM 堆大小 (Xms Xmx) 应该是多少