Pregunta

Me estoy haciendo OutOfMemoryError: montón de Java

fragmentos del método:

{
// 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
}

Mi Pregunta:

cada vez que este método se llama, está siendo creada la matriz. ¿Es posible que la matriz no está siendo puesto en libertad.

En las ventanas administrador de tareas puedo ver la memoria utilizada por Java es puramente incrementales. Así que no es que en un montón punto tamaño es menor, pero la memoria se utiliza de manera repetitiva y no se libera de alguna manera.

Por favor, hágamelo saber si necesita más detal.

Por favor, ayuda a depurar el error.

Anuj

La parte del código que podría estar causando el error:

int totalCombination = (int) Math.pow (2.0, (doble) 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]);
            }
        }
¿Fue útil?

Solución

potencias de dos crece exponencialmente. Si vowelCount es alta, una matriz solo puede causar fácilmente OutOfMemoryError (2^32 = 4GB).

Se puede tratar de ajustar su requisito de memoria máxima VM (por ejemplo -Xmx512m), pero se dan cuenta de que su algoritmo está requiriendo Una gran cantidad de memoria . Es posible que desee encontrar un mejor algoritmo, si es posible.


Ver también


Después de editar: justo lo que esperaba, se está generando una enorme variedad llena de todas las posibilidades binarias. Rara vez se necesita almacenar en realidad toda esta matriz en la memoria. Usted sólo puede generar cada combinación posible "en la marcha" y alimentar a quien lo necesite los 0s y 1s "just-in-time".

Tenga en cuenta que esto sigue siendo un crecimiento exponencial, por lo que a pesar de que se ha encargado de su requerimiento de memoria de O(2^N) sólo O(N), su complejidad temporal sigue siendo O(2^N).

  

cada vez que este método se llama, está siendo creada la matriz. ¿Es posible que la matriz no está siendo puesto en libertad.

Sí, eso es muy posible, si la referencia a la matriz se filtró vez, y luego algo en alguna parte se aferra a esta referencia. El recolector de basura no le importa lo que pensar es / no es basura; siempre y cuando un objeto se conoce por algo (y no es una referencia débil, etc), no es basura.


Después de averiguar lo que estás tratando de hacer, aquí está mi solución. Tenga en cuenta que no genera una matriz de bits en absoluto.

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");

Se utiliza expresiones regulares para encontrar en la siguiente vocal es. Se puede utilizar un habitual de bucle en lugar del algoritmo general y seguirá funcionando. Usted puede optimizar el uso StringBuilder lugar (estoy sobre todo a su favor la concisión y es de esperar claridad en este fragmento).


Aquí está una solución alternativa que utiliza split para pre-cortar la cadena de entrada en trozos (espacio O(N)), a continuación, utiliza un StringBuilder para generar todas las otras cuerdas (espacio 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");

Las divisiones de expresiones regulares en "apple" [ "a", "ppl", "e" ]. Se divide en todas partes después de una vocal, o (si no es el principio de la cadena) en todas partes antes de una vocal.

Debería ser obvio ahora que la necesidad de espacio es O(N), por lo menos que su cadena es ri , esto no debería causa OutOfMemoryError.

Por supuesto, si usted es almacenamiento las cadenas generadas - todo O(2^N) de ellos - en memoria a continuación, por supuesto obtendrá OutOfMemoryError. Espero que este hecho es evidente.

La idea entera es no almacenar en la memoria todo lo que no es necesario para generar este SALIDA enorme. Si a continuación, almacenar toda esta potencia de salida impresionante en la memoria (en lugar de, por ejemplo, la impresión de que stdout o un archivo), entonces en contra del propósito y obtendrá un OutOfMemoryError como se esperaba .

Otros consejos

Es posible que desee considerar el uso de un generador de perfiles que le puede dar una idea de lo que existe tipos de objetos en un momento dado en su programa. Como un ejemplo, NetBeans tiene un generador de perfiles incorporado.

Con eso se dice, la causa más probable es - como ha sido señalado por otros -. Extraordinariamente alta cantidad de memoria que su matriz bidimensional requerirá que el recuento vocal crece

Asumo que tiene algo así como el código siguiente:

int totalCombination = 1 << vowelCount;
System.out.println("totalCombination = " + totalCombination);
System.out.println("totalCombination (in Millions) = " + totalCombination / 1000 / 1000);

int[] arr = new int[totalCombination];

En un 32 bit VM la matriz no puede nunca crecer más allá de 4 GB, que es de 1024 millones de entradas. Asegúrese de que siempre conseguir un número menor imprimió en el código de seguridad.

Y tal vez debería tener un algoritmo completamente diferente. Pero para eso se tendría que decirnos lo que quiere lograr, no ¿Cómo que se están tratando.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top