Memory leaks dans OS 3.0

allianallian Membre
Salut à  tous j'ai depuis hier mon certificat officiel,
j'ai donc installé le nouvel SDK et tout le reste pour tester finalement sur mon device (3GS en passant).

Déjà  sur le simulateur j'ai d'énormes problèmes de mémoire, c'est à  dire que le jeu lag énormément !! à  prime abord je me suis dit que cela devait venir du Simulateur mais en faite non, sur le téléphone j'ai exactement le même problème alors qu'en 2.2 tout roulait parfaitement...

D'autres personnes ont elles rencontré ce genre de problèmes ??
Merci

Réponses

  • zoczoc Membre
    19:37 modifié #2
    Lag n'est pas synonyme de memory leaks...

    Sur l'iPhone en particulier, un memory leak important génère rapidement un crash de l'application par manque de mémoire (car il n'y a pas de système de mémoire virtuelle).

    La cause du problème est à  rechercher ailleurs. Pour cela l'outil "Instruments" est le plus adapté.
  • allianallian Membre
    19:37 modifié #3
    J'ai essayé de voir avec instruments mais j'arrive pas trop à  voir d'où cela peut venir...
    D'apres ce que j'en ai tiré mon app occupe 4-5MB de RAM ce qui est raisonnable je pense, parcontre niveau CPU c'est du 60-90% voir plus par moment !! je comprend pas comment cela est possible vu que je n'utilise pas OpenGLEs ni de 3D ??

    je met en PJ le save de Instruments. (mon app s'appelle Bleeker)
    Merci
  • Nebuchad34Nebuchad34 Membre
    juillet 2009 modifié #4
    dans 1246439740:

    J'ai essayé de voir avec instruments mais j'arrive pas trop à  voir d'où cela peut venir...
    D'apres ce que j'en ai tiré mon app occupe 4-5MB de RAM ce qui est raisonnable je pense, parcontre niveau CPU c'est du 60-90% voir plus par moment !! je comprend pas comment cela est possible vu que je n'utilise pas OpenGLEs ni de 3D ??


    Inutile de faire de la 3D pour solliciter le CPU... Il faut se souvenir que le CPU de l'iPhone est bien moins puissant que celui de ton Mac !

    Apparemment ton appli est un jeu, tu n'utilise pas openGL donc j'en déduit que tu travaille avec des UIView ; jusque là  tout va bien.

    Mais si tu fait des "setNeedDisplay" à  foison avec des uperposition de vues non opaques avec PNG transparents, ben faut pas s'étonner que ça rame  :)

    Par ailleurs, fait très attention à  ne pas te fier au simulateur pour la performance. Quelque chose de très fluide sur le simulateur peut très bien enterrer un iPhone. Fait d'autant plus attention à  tout ce qui peut bouffer du CPU, car tu as un iPhone 3GS, qui est donc plus puissant qu'un 2G ou qu'un 3G. Cela signifie que si ça lague un poilush sur ton 3GS, tu peut être sûr que ça va ramer à  mort sur les autres iPhone et iPod touch...

    Il faudrait que tu nous en dises plus sur ton code.

  • allianallian Membre
    19:37 modifié #5
    En effet mon jeu étant un pacman, je fais des setNeedsDisplay à  chaque fois qu'une boule est avalée, et mes personnages sont bien des png transparents...

    Du coup je dois faire quoi pour que ca aille mieux ?
    Mettre une croix sur mes PNG transparents ? ou autres ?
  • Nebuchad34Nebuchad34 Membre
    juillet 2009 modifié #6
    Non ce n'est pas la peine de faire un croix dessus, il faut juste pas en abuser. En l'occurence pour un Pacman ça devrait le faire.

    Encore un fois, sans code il sera difficile d'avancer quoi que ce soit.

    De toute façon, d'une manière générale, partout ou tu peux éviter la transparence, évite là  et passe tes vues en opaque. On peut très souvent remplacer l'usage de la transparence si le fond est de couleur unis par exemple
  • allianallian Membre
    juillet 2009 modifié #7
    En faite j'ai un pacman et 3 ennemis avec des bouches qui s'ouvrent et se ferment, en plus de cela il y a des bonus qui apparaissent et qui tournent sur eux mêmes.

    Je viens d'essayer de supprimer momentanément les bouches et les bonus, cava un peu mieux mais quand je bouge mon personnage ca lag encore..

    Je sais pas quoi te mettre comme code, il y en a pas mal donc je sais pas trop.


    EDIT : sous OS 2.2.1 cela fonctionnait très bien
  • Nebuchad34Nebuchad34 Membre
    19:37 modifié #8
    Tu n'as qu'à  mettre les drawRect des vues quer tu raffraichit souvent. Histoire de voir si c lourd ou pas.
  • allianallian Membre
    19:37 modifié #9
    En supprimant les setNeedsDisplay c'est presque parfait, cela commence à  ramer au bout d'un certain temps (un problème de dealloc je pense).
    Voici mon drawRect

    - (void)drawRect:(CGRect)rect {<br />&nbsp; &nbsp; // Drawing code<br />	<br />	CGFloat x,y;<br />	int i, j;<br />	<br />	UIColor *ballColor = [UIColor lightGrayColor];<br />	CGContextRef context = UIGraphicsGetCurrentContext();<br />	CGContextSetLineWidth(context, 2.0);<br />	CGContextSetStrokeColorWithColor(context, ballColor.CGColor);<br />	CGContextSetFillColorWithColor(context, ballColor.CGColor);<br />	<br />	for (i = 0; i &lt;= CASES_LARGEUR; i = i + 1)<br />	{<br />		for (j = 0; j &lt;= CASES_HAUTEUR; j = j + 1)<br />		{<br />			if (theLab[i][j] == 0)<br />			{<br />				x = TAILLE_CASE * j;<br />				y = TAILLE_CASE * i;<br />				CGRect currentRect = CGRectMake(x-2, y-2, 5, 5);<br />				CGContextAddEllipseInRect(context, currentRect);<br />				CGContextDrawPath(context, kCGPathFillStroke);<br />			}<br />		}<br /><br />	}<br />	<br />	UIColor *wallColor = [UIColor blackColor];<br />	CGContextSetLineWidth(context, 12.0);<br />	CGContextSetStrokeColorWithColor(context, wallColor.CGColor);<br />	CGContextSetFillColorWithColor(context, wallColor.CGColor);<br />	<br />	for (i = 0; i &lt;= CASES_LARGEUR; i = i + 1)<br />	{<br />		for (j = 0; j &lt;= CASES_HAUTEUR; j = j + 1)<br />		{<br />			if (theLab[i][j] == 1)<br />			{<br />				x = TAILLE_CASE * j;<br />				y = TAILLE_CASE * i;<br />				<br />				CGRect currentRect = CGRectMake(x-4, y-4, 8, 8);<br />				CGContextAddRect(context, currentRect);<br />				CGContextDrawPath(context, kCGPathFillStroke);<br />			}<br />		}<br />		<br />	}<br />	CGRect currentRect = CGRectMake(0, 300, 480, 50);<br />	CGContextAddRect(context, currentRect);<br />	CGContextDrawPath(context, kCGPathFillStroke);<br />	currentRect = CGRectMake(460, 290, 50, 50);<br />	CGContextAddRect(context, currentRect);<br />	CGContextDrawPath(context, kCGPathFillStroke);<br />	<br /><br /><br />}<br />
    
  • Nebuchad34Nebuchad34 Membre
    19:37 modifié #10
    C pas le genre de trucs très consommateurs ça...

    Le problème principal doit venir d'ailleurs, je vais consulter ton log d'instruments j'en serais peut etre plus
  • allianallian Membre
    19:37 modifié #11
    Je me disais aussi.
    Merci beaucoup de ton aide :D

    A mon avis cela vient plus d'un problème de mémoire.
  • Nebuchad34Nebuchad34 Membre
    19:37 modifié #12
    Euh, bof, ton log ne montre que la conso processeur, pas grand chose pour établir le lien avec ton code, et comme je ne suis pas un champion d'instruments...

    Lance instruments avec Leaks depuis XCODE (Run > Start With Performance Tool > Leaks) et regarde si tu n'a pas tout plein de pique oranges... pendant que tu joue à  ton jeu.

    Regarde aussi dans ton code si, par ailleurs, tu n'abuse pas des autorelease ce qui pourrait saturer ton runLoop et provoquer des ralentissements (je suppose)
  • allianallian Membre
    19:37 modifié #13
    J'ai déjà  utilisé Leaks et rien d'anormal, un pique parfois mais pas à  chaque partie donc rien d'inquietant je suppose.

    Les autorelease j'en utilise presque pas. Je fais tout à  la main ou presque et d'apres Clang GUI je n'ai pas fait d'oublis.

  • Nebuchad34Nebuchad34 Membre
    19:37 modifié #14
    Bien, bien, alors tout ça est bien curieux  ???

    Je t'aide là , hein ?  :)
  • allianallian Membre
    19:37 modifié #15
    C'est vraiment bizarre surtout que comme je t'ai dit sous OS 2.xx cela ne pose pas de problèmes...
  • MAGEMAGE Membre
    19:37 modifié #16
    S'il y a des pic de temps en temps avec Leaks, je chercherais tout de même à  savoir à  quelle occasion.

    De toute façon tu ne devrais pas en avoir du tout (à  mon avis ?)
  • Philippe49Philippe49 Membre
    19:37 modifié #17
    dans 1246451024:

    En faite j'ai un pacman et 3 ennemis avec des bouches qui s'ouvrent et se ferment, en plus de cela il y a des bonus qui apparaissent et qui tournent sur eux mêmes.

    Je viens d'essayer de supprimer momentanément les bouches et les bonus, cava un peu mieux mais quand je bouge mon personnage ca lag encore..

    Je sais pas quoi te mettre comme code, il y en a pas mal donc je sais pas trop.


    EDIT : sous OS 2.2.1 cela fonctionnait très bien

    Ce n'est sûrement pas une question de 3.0 contre 2.2.1.
    - Revoie la structure de ton code , un Pacman ne demande pas des ressources énormes si on pose correctement le problème.
    - Respecte la règle : "c'est au device/simulator de faire ses rafraichissement graphiques selon son rythme"
    - Fais tous les calculs avant de lancer un setNeedsDisplay
  • allianallian Membre
    19:37 modifié #18
    Alors pour vous expliquer je calcule le nouveau tableau contenant des 1 ou des 0 pour savoir s'il y a une boule ou pas dans ma classe gérant le pacman. Dans celle ci j'ai une méthode qui permet de bouger et dans cette derniere je calcule après chaque mouvement le nouveau tableau (maj ou pas).
    Une fois cela fait je passe à  ma méthode gérant le labyrinthe et donc son rafraichissement le nouveau tableau. Celle ci le parcours et dessine ou pas des boules et les murs.

    dans 1246524809:

    - Respecte la règle : "c'est au device/simulator de faire ses rafraichissement graphiques selon son rythme"


    Je viens de penser au fait que mon setNeedsDisplay est appelé à  chaque interval de ma méthode move qui est appelé toutes les 0.12 secondes tant que le joueur touche l'écran du coup c'est surement à  cause de cela.
  • allianallian Membre
    19:37 modifié #19
    J'ai réussi à  faire tourner l'appli normalement !!
    J'ai complétement changé la façon de faire, mon setNeedsDisplay est devenu setNeedsDisplayInRect du coup au lieu de tout redessiner je redessine uniquement un petit carré de 20 sur 20 et comme ça plus aucun soucis.

    Au passage j'utilise les différentes méthodes animation de UIImageView au lieu de faire ça à  la main et ca a l'air un peu moins gourmand aussi.

    Reste uniquement un petit lag occasionnel lorsque je joue un son. Pourtant j'utilise le prepareToPlay et le joue uniquement le moment voulu.
Connectez-vous ou Inscrivez-vous pour répondre.