Aller au contenu

Out Of Memory : comment les éviter ?


bsegonnes

Recommended Posts

Bonjour

De temps en temps (dans StringBuffer.append() je pense) j'ai des OOM.

J'ai pourtant encore pliens de RAM disponible (Runtime. freeMemory()).

Comment installer un callback qui lance une méthode (lors d'un OOM) à moi avec un beau DialogBox fait maison ?

La boite de dialogue standard d'Android indique que l'applie se plante : pas trés pro/beau :/

Merci

Lien vers le commentaire
Partager sur d’autres sites

c'est un cas un peux spécial le Out Of Memory :/ en plus dans les methodes 'de base' (StringBuffer.append() )

Juste avant mon Sb.append('h') je récupère la RAM dispo pour mon applie, j'ai environ 2Mo. Tout est donc OK (elle fonctionne encore quand il me reste que 500Ko)

La ligne suivante : sb.append('a') (un seul caractere) et : magnifique plantage

Bon, c'est vrai : il y a des boucles, et c'est pas la 1er fois que j'execute ce StringBuffer... mais bon : j'ai encore 2Mo de ram de libre :P

Lien vers le commentaire
Partager sur d’autres sites

t'as vraiment besoin d'un stringbuffer...une string ne suffit elle pas ?

ensuite un bon gros try/catch avec un point d'arret et tu devrais trouver le pb (inspecte ton stringbuffer tu peux avoir une surprise...) et la mémoire dans éclipse avec la vue DDMS....

sinon file le code qui déconne (avec les boucles....^^)

Lien vers le commentaire
Partager sur d’autres sites

...La ligne suivante : sb.append('a') (un seul caractere) et : magnifique plantage...

Parce qu'il instancie un nouveau buffer interne pour ce caractère, le précédent étant surement plein.

Essaie de voir avec les paramètres d'initialisation si tu as une idée de la taille finale pour éviter la multiplication des buffers

Les try/catch sur des Error doivent tout aussi bien fonctionner qu'en java mais il vaut mieux éviter de le faire car si elles sont levées c'est que ton appli ne peut pas tourner.

Lien vers le commentaire
Partager sur d’autres sites

>sinon file le code qui déconne (avec les boucles....^^)

Pas aussi simple d'isoler le code.

Ce code fonctionne trés bien dans pliens de cas.... Sauf qu'au bout d'un moment en reprenant un cas qui était OK, et après en avoir fait d'autres (lors de la même exécution de l'applie), et bien : la marchine virtuelle en a marre :-)

Je pense que je vais devoir en effet me passer de StringBuffer() .... pour en revenir à Android : êtes vous au courant de pb/bug avec StringBuffer sur Android ?

En gros ce que mon code fait :

- on envois une String

- on parcours tout les caractères et recopie dans la StringBuffer retournée que les caractères que je souhaite garder

Le tout bien sur des centaines de fois :)

Lien vers le commentaire
Partager sur d’autres sites

Je pense que je vais devoir en effet me passer de StringBuffer() .... pour en revenir à Android : êtes vous au courant de pb/bug avec StringBuffer sur Android ?

Tu vas instancier des String pour rien alors :

String string = "1"; -> 1 string en mémoire

string += "2"; -> 3 : "1", "2" et "12"

string += "3"; -> 5 : "1", "2", "12", "3" et "123"

string += "4"; -> 7 : "1", "2", "12", "3", "123", "4" et "1234"

OK, le garbage collector va en jeter plusieurs mais ce n'est pas optimisé du tout.

Par contre, à priori : String a = "1" + "2" + "3", ton compilateur doit le traduire tout seul en utilisation de StringBuffer.

Ton problème est surement ailleurs. Ou alors tu stocke plus de données que tu ne le penses (récursivité mal contrôlée ?).

Après, il est vrai qu'on peut constater des bizarreries dans le portage. ex : Date#toString() -> 1 sec par appel

Lien vers le commentaire
Partager sur d’autres sites

J'envois un String à ma methode en parametre.

Celle-ci vide le StringBuffer, puis ajoute des caractères. C'est la que çà plante trés rarement (OOM).

A la fin de la méthode je renvois un String correspondant au StringBuffer.

Puis la méthode est rappellée. Tout çà des centaines de fois.

Puis à un moment : Out of Memory dans le append('c') , alors qu'il me reste 2Mo de libre pour mon applie :-)

J'envois le code si j'ai l'occasion ce soir.

En fait mon problème (pour ne pas faire de hors sujet, et rester dans l'univers Android :cool: ) :

1) StringBuffer.append(char) est-il buggé ?

ou/et

2) comment lancer une méthode lorsque l'OS détecte qu'une application/Activity provoque un Out Of Memory

Lien vers le commentaire
Partager sur d’autres sites

A priori tu utilise try catch outofmemoryexceptoon et tu met le code dans le catch. ..

Ce que disait Jorodan en réponse immédiate au poste initial.

Certes...mais ce n'est pas parce qu'une exception est catchée qu'il faut l'ignorer.

La raison de ce out of memory devrait être résolu...non?!

Lien vers le commentaire
Partager sur d’autres sites

Certes...mais ce n'est pas parce qu'une exception est catchée qu'il faut l'ignorer.

La raison de ce out of memory devrait être résolu...non?!

Oui, c'est ce que je disais dans un précédent post, ca reste à éviter. Si tu n'as plus de mémoire, tu n'as plus de mémoire, c'est pas catcher l'Error qui va résoudre le problème et ramener de la mémoire. Pire, tu ne peux pas faire grand chose dans le catch vu que ... tu n'as plus de mémoire. 1/ Essayer de résoudre la cause 2/ si impossible faire un catch qui ne génère pas plus d'objet et terminera l'appli.

J'envois un String à ma methode en parametre.

Celle-ci vide le StringBuffer, puis ajoute des caractères. C'est la que çà plante trés rarement (OOM).

Ne peux-tu pas simplement instancier le StringBuffer à chaque appel ? J'imagine que tu as fait ça dans un soucis d'optimisation mais est-ce que tu n'as pas des problèmes de synchronisation par exemple ? Essaie peut être juste de l'instancier à chaque fois et/ou de vérifier le contenu de ton buffer :

try { /* ... do the job */ } catch (Error e) { /* log the buffer and exit */ }

Lien vers le commentaire
Partager sur d’autres sites

Certes...mais ce n'est pas parce qu'une exception est catchée qu'il faut l'ignorer.

La raison de ce out of memory devrait être résolu...non?!

Oui, bien sur.

Mais ça répond fortement à la question 2 :

"Comment lancer une méthode lorsque l'OS détecte qu'une application/Activity provoque un Out Of Memory ?"

Lien vers le commentaire
Partager sur d’autres sites

Certes...mais ce n'est pas parce qu'une exception est catchée qu'il faut l'ignorer.

La raison de ce out of memory devrait être résolu...non?!

Oui' date=' bien sur.

Mais ça répond fortement à la question 2 :

"Comment lancer une méthode lorsque l'OS détecte qu'une application/Activity provoque un Out Of Memory ?"[/quote']

Il ne faut pas lancer une activity...Il faut corriger le problème de out of memory! Comprendre la cause, corriger le problème...Sans dire que ton code est en cause, il doit y avoir un problème de conception ou de développement.

Lien vers le commentaire
Partager sur d’autres sites

Mon applie est prévus pour ouvrir des fichiers de divers types (pdf, doc, etc). La mémoire utilisé pour cette lecture de fichier dépend pas de sa taille (nb de Ko du fichier), mais des images, et autres trucs qu'il y a dedant.

je ne peux donc pas savoir au début si un fichier peut être lus sans probleme ou pas.

Je veux donc pouvoir sortir proprement, avec un beau message qui fait pas peur.

Il est donc pas possible d'éviter les Out Of Memory. Je veux juste changer la boite de dialogue standard de l'OS (l'Activity a crashée sans plus de précision) par la mienne.

Lien vers le commentaire
Partager sur d’autres sites

Plutot que chargé l'ensemble du document en mémoire, n'as tu pas moyen de faire un chargement page par page? Ce qui:

1. prendrait moins de temps au chargement

2. limiterait la taille mémoire

Je ne sais pas comment est construite ton appli, mais tu pourrais faire un lecture page par page, utilisant un objet Page (par exemple) qui serait modifié à chaque nouvelle page.

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...