Aller au contenu

Out Of Memory : comment les éviter ?


bsegonnes

Recommended Posts

J'utilise des librairies que je ne maitrise pas (pdfbox,poi). Je genre d'usine à gaz comprenant plus de 100 .java !

J'ai pas l'itention de débugger tout çà. A la limite, j'optimise (supprime) le code dont je suis sur qu'il me sert à rien (après des tonnes de tests de non-reg.). Mais le code qui est vital : j'y touche pas :D

Lien vers le commentaire
Partager sur d’autres sites

dans ce cas :

try

{

.... ton code

} catch(Exceptionjesaispasquoi)

{

... message d'erreur

System.Exit(0);

}

Mais bon à mon avis pour les gros fichiers sur plateforme mobile il doit falloir passer par un fichier sur disque (un FileBuffer si ça existe pour stocker tes données plutot qu'un stringbuffer)...du coup la chaine est stockée dans les datas de tes 8G de carte ^^ (et là avant de péter le OOM t'as de la marge)

Lien vers le commentaire
Partager sur d’autres sites

Plus ou moins résolue.

J'ai plus mon Out Of Memory, mais je sais toujours pas comment l'intercepter.

Une petite info si d'autres personnes tombent sur ce 'bug' de la JVM :

Le code suivant fonctionne bien environ 250 fois, puis OOM :

private final StringBuffer sb = new StringBuffer(256);

protected String removeBadCharacter(final String s) {

sb.setLength(0);

char[] charS = s.toCharArray();

int charSLen = charS.length;

boolean isThereSomethingToRead = false;

for(int i=0;i

char c = charS[ i ];

char cPrevious = (i>0)? charS[ i-1 ] : (char)0;

if( (c=='\n') || (c=='\r') ) c=' ';

// special case for number : don't cut sentence when '.'

if( (c=='.') &&

( (i>0) && (Character.isDigit(charS[ i-1 ])) ) &&

( (i+1) < charSLen) && (Character.isDigit(charS[ i+1 ])) ) {

sb.append©;

isThereSomethingToRead = true;

}

else if(Character.isLetterOrDigit© ) {

try {

sb.append© <------- Ouf Of Memory de temps en temps;

}

catch(Exception e) {

android.util.Log.d("MultiReader","Out of Memory : c = "+c);

}

isThereSomethingToRead = true;

}

else if(Character.isWhitespace© ) {

sb.append©;

}

else if((c=='.') || (c==',') || (c==';') || (c=='\"') || (c=='\'') || (c=='/') || (c=='?') ) {

if( (cPrevious!='.') && (cPrevious!=',') && (cPrevious!=';') && (cPrevious!='\"') && (cPrevious!='\'') && (cPrevious!='/') && (cPrevious!='?') )

sb.append©;

}

// else replace all other characters by ' '

else

sb.append(' ');

}

// if we only have ' ' ; , - or unknown character : don't return any string

if(isThereSomethingToRead==false) return null;

if(sb.length() >0) return sb.toString();

return null;

} // end of removeBadCharacter()

Ma solution : ne plus utilise de StringBuffer :D :

protected String removeBadCharacter(final String s) {

char[] cWithoutBadCharacters = new char[s.length()];

int cWithoutBadCharactersLength = 0;

char[] cWithBadCaracters = s.toCharArray();

int cWithBadCaractersLen = cWithBadCaracters.length;

for(int i=0;i

char c = cWithBadCaracters[ i ];

char cPrevious = (i>0)? cWithBadCaracters[ i-1 ] : (char)0;

if( (c=='\n') || (c=='\r') ) c=' ';

// special case for number : don't cut sentence when '.'

if( (c=='.') &&

( (i>0) && (Character.isDigit(cWithBadCaracters[ i-1 ])) ) &&

( (i+1) < cWithBadCaractersLen) && (Character.isDigit(cWithBadCaracters[ i+1 ])) ) {

cWithoutBadCharacters[cWithoutBadCharactersLength++] = c;

}

else if(Character.isLetterOrDigit© ) {

cWithoutBadCharacters[cWithoutBadCharactersLength++] = c;

}

else if(Character.isWhitespace© ) {

cWithoutBadCharacters[cWithoutBadCharactersLength++] = c;

}

else if((c=='.') || (c==',') || (c==';') || (c=='\"') || (c=='\'') || (c=='/') || (c=='?') ) {

if( (cPrevious!='.') && (cPrevious!=',') && (cPrevious!=';') && (cPrevious!='\"') && (cPrevious!='\'') && (cPrevious!='/') && (cPrevious!='?') )

cWithoutBadCharacters[cWithoutBadCharactersLength++] = c;

}

// else replace all other characters by ' '

else

cWithoutBadCharacters[cWithoutBadCharactersLength++] = ' ';

}

// if we only have ' ' ; , - or unknown character : don't return any string

if(cWithoutBadCharactersLength>0) return new String(cWithoutBadCharacters);

return null;

} // end of removeBadCharacter()

Modifié par bsegonnes
Lien vers le commentaire
Partager sur d’autres sites

Alors en plus arrete de déclarer tes variables en final. T avais essayé avec un stringbuffer non final. ..

Ton sb n est jamais libéré . Le setlenghth(0) LE tronque mais ne desalloue pas la mémoire.

Modifié par popolbx
Lien vers le commentaire
Partager sur d’autres sites

Alors en plus arrete de déclarer tes variables en final. T avais essayé avec un stringbuffer non final. ...

C'est la référence qui est final, pas le StringBuffer, ca n'aurait rien changé. Je ne peux que vous conseiller d'utiliser tout le temps des variables final, vous clarifierez votre code. (je parle des variables locales de méthodes surtout)

try {

sb.append© <------- Ouf Of Memory de temps en temps;

}

catch(Exception e) {

android.util.Log.d("MultiReader","Out of Memory : c = "+c);

}

J'ai donné la syntaxe dans un précédent post, OutOfMemoryError, comme son nom l'indique, n'est pas une Exception mais une Error.

Pourquoi garder toujours le même StringBuffer qui gardera en mémoire les données même si tu n'en as plus besoin et ce pendant toute la durée de vie de ton objet englobant ?

Ecrit plutôt :

protected String removeBadCharacter(final String s) {

final StringBuffer sb = new StringBuffer(s.length());

Note : j'ai pas vraiment essayé de comprendre ton code, il y a donc peut être une vraie fuite mémoire ailleurs.

Lien vers le commentaire
Partager sur d’autres sites

Hello,

comme dit il faut catcher les OutOfMemoryError si tu veux les gérer mais c'est en général difficiles à gérer de toute façon.

Pour ton code, si je comprends bien tu cherches à :

- mettre ton texte sur une ligne

- supprimer les doublons de ponctuation

Ce doit être possible de l'écrire plus simplement à l'aide des classes Matcher et Pattern de java.util.regex(-> http://developer.android.com/reference/java/util/regex/Pattern.html)

Surement en deux étapes par contre donc pas sur que ce soit moins consommateur de mémoire sur le moment. Mais ça doit marcher.

Bon courage

Lien vers le commentaire
Partager sur d’autres sites

Rejoignez la conversation

Vous pouvez poster maintenant et vous enregistrez plus tard. Si vous avez un compte, connectez-vous maintenant pour poster.

Invité
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Répondre à ce sujet…

×   Collé en tant que texte enrichi.   Coller en tant que texte brut à la place

  Seulement 75 émoticônes maximum sont autorisées.

×   Votre lien a été automatiquement intégré.   Afficher plutôt comme un lien

×   Votre contenu précédent a été rétabli.   Vider l’éditeur

×   Vous ne pouvez pas directement coller des images. Envoyez-les depuis votre ordinateur ou insérez-les depuis une URL.

×
×
  • Créer...