Application un peu gourmande en memoire

sebrs1 Messages postés 81 Date d'inscription dimanche 15 avril 2001 Statut Membre Dernière intervention 20 novembre 2012 - 19 nov. 2012 à 15:00
cs_Julien39 Messages postés 6414 Date d'inscription mardi 8 mars 2005 Statut Modérateur Dernière intervention 29 juillet 2020 - 20 nov. 2012 à 14:25
Salut les gens,
J'ai une application déjà publié sur le play store.
Elle s’appelle Ephemeridroid. C'est un widget configurable qui permet d'avoir l’éphéméride du jour avec des options de notifications contacts, personnalisation graphique ...
Un utilisateur m'a dit que l'appli bouffait vachement de mémoire, jusqu’à 55mo .... effectivement cela peut faire un peu beaucoup pour un widget.
Le truc c'est que je ne sais pas ce qui peut provoquer cela, des activity mal fermées, des tableau non nettoyés (mais normalement en java pas besoin non?) ...
je suis développeur de métier mais le java c'est juste a titre personnel et je suis pas une tête et j'avoue que je sais pas trop de quel coté chercher ce genre de truc.
Dans mon application, je manipule des bitmap (pour les thèmes), je manipule des tableaux , .... des dates.. bref voila en gros
est-ce que vous auriez des pistes, ou même ptetre un outil interne ou externe a éclipse qui permet de pister le soucis??

merki d'avance

19 réponses

cs_Julien39 Messages postés 6414 Date d'inscription mardi 8 mars 2005 Statut Modérateur Dernière intervention 29 juillet 2020 371
19 nov. 2012 à 15:39
Salut,

Je ne connais pas vraiment d'outil qui permet de tracer le soucis.

Par contre :
- Tu n'as pas besoin de nettoyer les variables, ni les tableaux, le garbage collector le fait pour toi.
- Si tu lances des threads, il faut bien vérifier que tu les arrêtes. Penses à fermer les flux si tu les utilises.
- Vu l'application, 55Mo, ca fait beaucoup, tu dois enregistrer quelque part des objets qui contiennent des images et continuer à les référencer dans ton code de manière à ce qu'ils ne soient pas détruits par le Garbage collector.

Après, je ne comprends pas vraiment ce que tu entends par tableaux non nettoyés, bien sur que si, il faut que tu sortes les objets qui ne sont plus utilisés dans tes tableaux, sinon, l'espace mémoire associé n'est jamais nettoyé. Tu peux utiliser les arrayList pour pouvoir redimensionner plus facilement les tableaux, mais il faut bien les vider.
0
sebrs1 Messages postés 81 Date d'inscription dimanche 15 avril 2001 Statut Membre Dernière intervention 20 novembre 2012
19 nov. 2012 à 15:50
Nan je ne lance pas de thread, j'ai juste un service qui tourne a interval regulier pour mettre a jour le widget mais en dehors de ça rien de plus.

Pour les variable et tableaux il me semblais bien que le GC s'occupais de tout.

Après j'ai par exemple une ListActivity qui contient 366 elements (simples) je sais pas si ce genre de liste peut bouffer bcp de memoire ou si il faut ferme proprement une activity plutot qu'elle reste chargée en arrière plan.
si t'as deux minutes à tuer, regarde l'application et si tu vois un truc qui pourrais te faire dire par exemple "Ah, peut-etre qu'il vide pas bien tel ou tel truc, ou une image qui reste chargée", toute remarque est la bienvenue
0
BunoCS Messages postés 15476 Date d'inscription lundi 11 juillet 2005 Statut Modérateur Dernière intervention 3 mai 2024 103
19 nov. 2012 à 16:07
Hello,
Pour les variable et tableaux il me semblais bien que le GC s'occupais de tout.

S'il n'y a pas de référence sur l'objet! En gros, si ton objet est mis à null.

Après j'ai par exemple une ListActivity qui contient 366 elements

ça peut compter...As-tu utiliser un système de recyclage d'items?

@+
Buno, Admin CS
L'urgent est fait, l'impossible est en cours. Pour les miracles, prévoir un délai...
0
cs_Julien39 Messages postés 6414 Date d'inscription mardi 8 mars 2005 Statut Modérateur Dernière intervention 29 juillet 2020 371
19 nov. 2012 à 16:08
Pour les variables et les tableaux, le GC s'en occupe mais il ne faut pas que ces éléments restent référencés.

Par exemple, si tu créés une classe qui contient un tableau, si la classe n'est plus référencée alors, tout est nettoyé.

Par contre, si tu créés un tableau en static ou dans un singleton, ou dans une instance d'une classe qui n'est pas vouée à être supprimée alors rien n'est nettoyé.

En fonction de la taille de ton code, je peux jeter un oeil, dis moi où je peux le récupérer et je regarderai.
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
sebrs1 Messages postés 81 Date d'inscription dimanche 15 avril 2001 Statut Membre Dernière intervention 20 novembre 2012
19 nov. 2012 à 16:09
recyclage? moi pas connaitre
0
cs_Julien39 Messages postés 6414 Date d'inscription mardi 8 mars 2005 Statut Modérateur Dernière intervention 29 juillet 2020 371
19 nov. 2012 à 16:10
Petite précision :
S'il n'y a pas de référence sur l'objet! En gros, si ton objet est mis à null.

Ceci ne signifie pas que tu dois passer ton objet à null en faisant obj=null;
0
BunoCS Messages postés 15476 Date d'inscription lundi 11 juillet 2005 Statut Modérateur Dernière intervention 3 mai 2024 103
19 nov. 2012 à 17:29
Pour le recyclage, 1ère partie de ce post


@+
Buno, Admin CS
L'urgent est fait, l'impossible est en cours. Pour les miracles, prévoir un délai...
0
BunoCS Messages postés 15476 Date d'inscription lundi 11 juillet 2005 Statut Modérateur Dernière intervention 3 mai 2024 103
19 nov. 2012 à 17:30
Avec peut-être un peu plus d'explication


@+
Buno, Admin CS
L'urgent est fait, l'impossible est en cours. Pour les miracles, prévoir un délai...
0
sebrs1 Messages postés 81 Date d'inscription dimanche 15 avril 2001 Statut Membre Dernière intervention 20 novembre 2012
19 nov. 2012 à 17:42
Ok bon jpeux essayer ça. Cela dit dans l'article ils parlent d'un milliard d'enregistrement, j'en suis assez loin :)
Mais pourquoi pas essayer, ça ne peut en être que bénéfique.
0
Twinuts Messages postés 5375 Date d'inscription dimanche 4 mai 2003 Statut Modérateur Dernière intervention 14 juin 2023 111
19 nov. 2012 à 21:55
Salut,

Je suis sur la même idée que buno concernant tes 366 items.


Après il y a pas de secrets:
faire du debug avec DDMS et également faire du profiling avec dmtracedump

Autre thread intéressant ICI



-----

"On n'est pas au resto : ici on ne fait pas dans les plats tout cuits ..."

OoWORAoO
0
sebrs1 Messages postés 81 Date d'inscription dimanche 15 avril 2001 Statut Membre Dernière intervention 20 novembre 2012
20 nov. 2012 à 01:10
Bon un petit retour sur mon debug : grosses interrogations !!
Voila ce qui en partie foutait la merde dans mon application
EphemerideTrans = EphemerideTrans.replaceAll("ste ","");
EphemerideTrans est un String

corrigé en
EphemerideTrans = EphemerideTrans.replace("ste ","");

maintenant interrogations :
Pourquoi l'usage répété de cette fonction fini par me bouffer 10 a 15 mo de RAM?
y'a des precautions à prendre avec les String qui pourraient bouffer de la memoire?

et question subsidiaire, y'a d'autre pièges de ce genre a éviter? en java?
0
sebrs1 Messages postés 81 Date d'inscription dimanche 15 avril 2001 Statut Membre Dernière intervention 20 novembre 2012
20 nov. 2012 à 01:17
j'ai aussi l'impression que l'usage répétée de replace fini au final par me bouffer de la mémoire, moins vite mais qd meme de façon importante
0
cs_Julien39 Messages postés 6414 Date d'inscription mardi 8 mars 2005 Statut Modérateur Dernière intervention 29 juillet 2020 371
20 nov. 2012 à 09:26
Salut,

Fonctionnellement, replace et replaceAll, ce n'est pas exactement la même chose.

Et je ne vois absolument pas pourquoi cet appel te bouffe de la mémoire, c'est une fonction simple...

Il y a bien des précautions à prendre avec les String lors de la concaténation par exemple :
//Cette simple ligne créé 8 objets pour réussir à créer s
String s = "a" + "b" + "c" + "d";
// Le code ci dessous n'en créé que 6
StringBuilder sb = new StringBuilder();
sb.append("a");
sb.append("b");
sb.append("c");
sb.append("d");
String s = sb.toString();


String est une classe qui contient un tableau de char, et donc, la concaténation entraîne la création d'un nouveau tableau et ca peut être assez long.

Si tu fais une boucle pour créer une chaîne de caractères, il vaut mieux utiliser les StringBuilder qui permettent d'économiser un peu de mémoire.

NB : l'exemple que je t'ai donné est assez mal choisit, l'économie réalisée n'est pas énorme mais en général, ca vaut le coup.
0
cs_jojolemariole Messages postés 519 Date d'inscription mercredi 21 mars 2007 Statut Membre Dernière intervention 19 décembre 2016 25
20 nov. 2012 à 09:53
La concaténation via des String (statiques) consomme surtout plus de temps, c'est d'une complexité quadratique alors la concaténation via des StringBuffer ou des StringBuilder (dynamiques) est de complexité linéaire.

Pour s'en convaincre :

public class Test {

public static void main(String[] args) {

int length = 100000;

// avec un String
long t0 = System.currentTimeMillis();
String aaa = "";

while (aaa.length() < length) {
aaa += 'a';
}

long t1 = System.currentTimeMillis();
System.out.println("concat String : " + (t1 - t0) + "ms");

// avec un StringBuffer
t0 = System.currentTimeMillis();
StringBuilder bbb = new StringBuilder();

while (bbb.length() < length) {
bbb.append('b');
}

t1 = System.currentTimeMillis();
System.out.println("concat StringBuilder : " + (t1 - t0) + "ms");
}
}
0
sebrs1 Messages postés 81 Date d'inscription dimanche 15 avril 2001 Statut Membre Dernière intervention 20 novembre 2012
20 nov. 2012 à 10:07
Après mes manipulations de chaine ne se résument pas a de la simple concaténation Je dirais que les opérations les plus souvent réalisées dans mon application c'est de la recherche de chaîne et justement les replace

par exemple j'ai un contact qui s’appelle Jacques martin et j'ai une fête "St jacques de Compostelle" donc je dois couper mon contact suivant les espaces pour vérifier que jacques ou martin apparait dans l’éphéméride a tester.

enfin voila ce genre de truc. Vous pensez que les Stringbuilder serait toujours plus appropriés?
0
cs_jojolemariole Messages postés 519 Date d'inscription mercredi 21 mars 2007 Statut Membre Dernière intervention 19 décembre 2016 25
20 nov. 2012 à 11:48
Non, pour faire des replace je ne pense pas que ce soit utile d'utiliser des StringBuilder, surtout sur des chaînes aussi courtes.

J'intervenais juste pour confirmer que la concaténation entre 2 String n'étais pas une opération anodine.

À mon avis, il faut chercher ailleurs. Je ne connais pas du tout les applis java mobile mais t'es-tu renseigné sur la consommation "normale" de ce genre d'applis en mémoire ?

Tu peux aussi regarder si tu charges beaucoup de BufferedImage (4 octets par pixels en ARGB pour rappel, car 0 compression). J'ai vu que tu parlais de Bitmap, peux-tu expliciter ?
0
cs_Julien39 Messages postés 6414 Date d'inscription mardi 8 mars 2005 Statut Modérateur Dernière intervention 29 juillet 2020 371
20 nov. 2012 à 14:02
Tu n'as pas besoin de découper ta chaîne pour faire une recherche :

	public static void main(String[] args) {
String recherche = "jacques martin";
String regex = "(.*"+recherche.replaceAll("\\p{Space}", ".*)|(.*")+".*)";
System.out.println("saint jacques de compostelle".matches(regex));
}
0
sebrs1 Messages postés 81 Date d'inscription dimanche 15 avril 2001 Statut Membre Dernière intervention 20 novembre 2012
20 nov. 2012 à 14:20
ouai mais là on en revient a replaceAll qui me bouffe de la mémoire a toc , et je ne sais pas pourquoi
0
cs_Julien39 Messages postés 6414 Date d'inscription mardi 8 mars 2005 Statut Modérateur Dernière intervention 29 juillet 2020 371
20 nov. 2012 à 14:25
Ce n'est absolument pas normal que replaceAll te bouffe de la mémoire, tu dois l'utiliser dans une boucle ou quelque chose comme ça.

Si tu découpes ta chaîne, ce sera nécessairement plus lourd.
0
Rejoignez-nous