Domanda

Io sono sempre OutOfMemoryError: java mucchio

frammenti del metodo:

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

La mia domanda:

ogni volta che viene chiamato questo metodo, si sta creato tale matrice. E 'possibile che la matrice non è sempre rilasciato.

In finestre taskmanager posso vedere memoria utilizzata da Java è puramente incrementale. Quindi non è che in un punto mucchio dimensioni è minore, ma la memoria è ripetutamente usato e non rilasciato in qualche modo.

Per favore fatemi sapere se avete bisogno di più detal.

Si prega di aiuto per eseguire il debug l'errore.

Anuj

La parte di codice che potrebbe essere la causa l'errore:

int totalCombination = (int) Math.pow (2,0, (doppio) 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]);
            }
        }
È stato utile?

Soluzione

potenze di due cresce in modo esponenziale. Se vowelCount è alto, un array sola potrebbe facilmente causare OutOfMemoryError (2^32 = 4GB).

Si può cercare di ottimizzare il vostro requisito di memoria massima VM (ad esempio -Xmx512m), ma si rendono conto che l'algoritmo sta richiedendo un sacco di memoria . Si consiglia di trovare un algoritmo migliore, se possibile.


Vedi anche


Dopo edit: proprio come mi aspettavo, si sta generando una matrice enorme pieno di tutte le possibilità binari. Raramente è necessario memorizzare in realtà tutta questa matrice nella memoria. Si può solo generare ogni possibile combinazione "on-the-fly" e dei mangimi a chi ha bisogno degli 0 e 1 "just-in-time".

Non tenere a mente che questo è ancora una crescita esponenziale, quindi, anche se hai preso cura del proprio fabbisogno di memoria da O(2^N) a poco O(N), il vostro tempo è ancora la complessità O(2^N).

  

ogni volta che viene chiamato questo metodo, si sta creato tale matrice. E 'possibile che la matrice non è sempre rilasciato.

Sì, è molto possibile, se il riferimento alla matrice è mai trapelato, e poi qualcosa da qualche parte tiene a questo riferimento. Il garbage collector in realtà non importa che cosa si pensare è / non è spazzatura; fintanto che un oggetto viene definito da qualcosa (e non è un riferimento debole, ecc), non è spazzatura.


Dopo capire quello che stai cercando di fare, ecco la mia soluzione. Si noti che non genera una matrice di bit affatto.

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

Si utilizza regex per trovare dove il prossimo vocale è. È possibile utilizzare un normale ciclo for, invece, e l'algoritmo generale continueranno a funzionare. È possibile ottimizzare in modo da utilizzare al posto StringBuilder (Sono per lo più andando per concisione e, auspicabilmente, la chiarezza in questo frammento).


Ecco una soluzione alternativa che usi split pre-tagliare la stringa di input in pezzi (spazio O(N)), quindi utilizza un StringBuilder per generare tutte le altre corde (spazio 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");

I divide regex "apple" in [ "a", "ppl", "e" ]. Si divide in tutto il mondo dopo una vocale, o (se non è l'inizio della stringa) in tutto il mondo prima di una vocale.

Dovrebbe essere ovvio, ora che il fabbisogno di spazio è O(N), quindi a meno che la stringa è assurdamente lunghi , questo non dovrebbe causare OutOfMemoryError.

Naturalmente, se si sta memorizzazione le stringhe generate - tutte O(2^N) di loro - in memoria quindi ovviamente si otterrà OutOfMemoryError. Spero che questo fatto è evidente.

L'intera idea è quello di non memorizzare tutto ciò che non è necessario per generare questo USCITA ENORME. Se poi memorizzare tutti di questa uscita enorme in memoria (invece che, per esempio, li stampa su stdout o un file) allora sconfigge l'intero scopo e si otterrà un OutOfMemoryError come previsto .

Altri suggerimenti

Si potrebbe desiderare di considerare l'utilizzo di un profiler che si può dare un quadro di ciò che esiste tipi di oggetti in un dato momento nel vostro programma. Come un esempio, NetBeans ha un profiler integrato.

Con questo detto, il probabile colpevole è - come è stato sottolineato da altri -. Straordinariamente elevata quantità di memoria che il vostro array bidimensionale richiederà come il conteggio di vocale cresce

I suppone che si abbia qualcosa di simile al seguente codice:

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

int[] arr = new int[totalCombination];

In un 32 bit VM la matrice non può mai crescere ulteriormente di 4 GB, che è di 1024 milioni di voci. Assicurati di ottenere sempre più piccoli numeri stampati in codice di cui sopra.

E forse si dovrebbe prendere un algoritmo completamente diverso. Ma per quello che avrebbe dovuto dirci che cosa si vuole raggiungere, non come si sta tentando di esso.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top