Question

Je suis OutOfMemoryError:java heap

extraits de la méthode:

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

Ma Question:

chaque fois que cette méthode est appelée, ce tableau est de se créer.Est-il possible que le tableau n'est pas libérée .

Dans le gestionnaire des tâches de windows, je peux voir la mémoire utilisée par java est purement incrémentale.Il n'est donc pas qu'à un point de la taille du segment est de moins en moins, mais la mémoire est utilisé de façon répétitive et pas libéré d'une certaine manière.

S'il vous plaît laissez-moi savoir si vous avez besoin de plus detal.

S'il vous plaît aider à chercher l'erreur.

Anuj

La partie du code qui pourrait être la cause de l'erreur:

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]);
            }
        }
Était-ce utile?

La solution

Les puissances de deux croît de façon exponentielle.Si vowelCount est haut, un tableau à lui seul pourrait facilement causer des OutOfMemoryError (2^32 = 4GB).

Vous pouvez essayer de modifier votre VM maximum les besoins en mémoire (par ex. -Xmx512m), mais ne compte que votre algorithme est exigeant BEAUCOUP DE MÉMOIRE.Vous voulez trouver un meilleur algorithme, si possible.


Voir aussi


Après la modification:comme je m'y attendais, vous êtes la génération d'un tableau énorme rempli avec tous les possibilités.Vous aurez rarement besoin de stocker l'ensemble de ce tableau dans la mémoire.Vous pouvez tout simplement de générer chaque combinaison possible "à la volée" et le donner à celui qui a besoin de l'0s et 1s "juste-à-temps".

Ne gardez à l'esprit que c'est toujours en croissance exponentielle, de sorte que même si vous avez pris soin de votre exigence de mémoire de O(2^N) juste O(N), le temps de la complexité est encore O(2^N).

chaque fois que cette méthode est appelée, ce tableau est de se créer.Est-il possible que le tableau n'est pas libérée .

Oui, c'est très possible, si la référence à la matrice est jamais fui, et puis quelque chose quelque part tient à cette référence.Le garbage collector n'est pas vraiment attention à ce vous pense est/n'est pas des ordures;tant qu'un objet est visé par quelque chose (et ce n'est pas une référence faible, etc), il ne sont PAS des déchets.


Après de savoir ce que vous êtes en train de faire, voici ma solution.Notez qu'il n'est pas de générer un tableau de bits à tous.

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

Il utilise les regex pour trouver l'endroit où la prochaine voyelle.Vous pouvez utiliser un boucle for à la place, et l'algorithme général continuera de fonctionner.Vous pouvez optimiser l'utilisation StringBuilder au lieu de cela (je suis principalement pour la concision et espérons-le, plus de clarté dans cet extrait).


Voici une solution alternative qui utilise split pré-couper la chaîne d'entrée en morceaux (à l'O(N) de l'espace), puis utilise un StringBuilder générer toutes les autres chaînes (O(N) de l'espace).

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

La regex divise "apple" en [ "a", "ppl", "e" ].Il se divise partout après une voyelle, ou (si c'est pas le début de la chaîne) partout devant une voyelle.

Il devrait être évident maintenant que l'espace est O(N), et , sauf si votre chaîne est ridiculement long, cela ne devrait pas causer de OutOfMemoryError.

Bien sûr, si vous êtes le stockage l'généré de chaînes-tous les O(2^N) de-dans de la mémoire alors bien sûr vous obtiendrez OutOfMemoryError.J'espère que ce fait est évident.

L'idée entière est de ne pas les stocker dans la mémoire de tout ce que vous n'avez pas besoin de générer cette IMMENSE production.Si vous puis de stocker l'ensemble de cette IMMENSE production en mémoire (au lieu de, disons, de l'impression à stdout ou un fichier), puis il va à l'encontre de l'objectif et vous aurez une OutOfMemoryError comme prévu.

Autres conseils

Vous pouvez envisager d'utiliser un profiler qui peut vous donner une idée de quels types d'objets existe à un moment donné dans votre programme.À titre d'exemple, NetBeans est doté d'un générateur de profils.

Avec cela étant dit, le probable est--comme cela a été souligné par d'autres -, la très grande quantité de mémoire que votre tableau à deux dimensions exigera que la voyelle compter grandit.

Je suppose que vous avez quelque chose comme le code suivant:

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

int[] arr = new int[totalCombination];

Dans un 32 bits, VM le tableau ne peut pas toujours pousser plus loin que de 4 GO, qui est de 1 024 millions d'entrées.Assurez-vous de toujours obtenir de plus petits numéros imprimés dans le code ci-dessus.

Et peut-être vous devriez prendre un de complètement différent de l'algorithme.Mais pour cela, vous devez nous dire ce que vous voulez atteindre, pas comment vous êtes en train de l'essayer.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top