Gestion de fichier lourd (plusieurs Go)

2»

Réponses

  • AliGatorAliGator Membre, Modérateur
    janvier 2006 modifié #32
    Ben oui c'est comme ça qu'il faut faire, c'est ce que l'on vient en effet d'expliquer.

    Sans la création d'un autoreleasepool local, les variables autoreleasées (genre readHandle) ne sont libérées qu'à  la fin de la RunLoop.
    Donc dans ton cas bien après que la boucle while soit terminée (une fois que tu sors de la fonction, de la fonction qui a appelé cette fonction, etc). Entre temps, la mémoire n'est donc pas libérée, pas avant la fin de la boucle while et de ta RunLoop.

    D'où l'idée de créer une autoreleasePool, qui va venir se rajouter dans la pile des autoreleasepools. En effet, les objets qui sont autoreleased s'ajoutent toujours à  la dernière autoreleasePool créée. Et c'est quand tu envoie un "release" à  l'autoreleasepool qui les contient qu'ils sont libérés (qu'il leur est envoyé un "release" à  eux aussi).
    C'est comme ça que ça marche avec l'autoreleasepool créée par Cocoa et qui t'es transparente : une nouvelle autoreleasepool est créée à  chaque début de RunLoop, et releasée à  chaque fin de RunLoop, envoyant du même coup un release à  tous les objets qu'elle contient.

    En créant une autoreleasePool locale, tous les objets qui sont autorelease (genre ton readHandle) sont mis dans cette autoreleasePool locale au lieu de celle de la RunLoop de ton programme. Ce qui te permet de libérer ces objets à  la fin de chaque itération au lieu d'attendre la fin de la RunLoop, en releasant ton autoreleasepool locale à  la fin de chaque itération, sans attendre la fin de toute la boucle while.

    Violà , voilà .


    Bon ça ne répond pas à  la question que j'ai posée à  SuperMic sur img2 : on envoie à  img2 les messages alloc/init puis release, dans la boucle while donnée en exemple. A chaque itération on gère nous-même l'alloc/init et le release, il n'y a pas d'autorelease qui intervient ici. img2 est donc bien releasée, et l'espace mémoire qu'il occupait est libéré. Et ce à  chaque itération dans la boucle. Donc je ne comprends pas pourquoi avec cette boucle tu dises que ça continue d'occuper 240 et qques Mo ???
    NSImage *img=[[NSImage alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForImageResource:@&quot;globe&quot;]];<br />	int i;<br />	NSData *dat;<br />	dat=[img TIFFRepresentation];<br />	for (i=0;i&lt;20;i++)<br />	{<br />		NSImage *img2=[[NSImage alloc] initWithData:dat];<br />		[img2 release];<br />	}<br />	return;
    

    SuperMic a écrit:
    Ce n'est qu'un exemple, certes ton code prend moins de mémoire puis le TIFFRep n'est demandé qu'une fois... mais la mémoire allouée à  img2 reste toujours monopolisée (360Mo) jusqu'à  la fin de la boucle.
  • 12:18 modifié #33
    Alig > tu as essayé ?

    Je n'en sais pas plus. C'est juste une remarque. Le système ne récupère pas de suite la mémoire alors qu'avec l'autoreleasepool oui.
  • BruBru Membre
    12:18 modifié #34
    dans 1136393672:

    Bon ça ne répond pas à  la question que j'ai posée à  SuperMic sur img2 : on envoie à  img2 les messages alloc/init puis release, dans la boucle while donnée en exemple. A chaque itération on gère nous-même l'alloc/init et le release, il n'y a pas d'autorelease qui intervient ici. img2 est donc bien releasée, et l'espace mémoire qu'il occupait est libéré. Et ce à  chaque itération dans la boucle. Donc je ne comprends pas pourquoi avec cette boucle tu dises que ça continue d'occuper 240 et qques Mo ???


    dans 1136400499:

    Je n'en sais pas plus. C'est juste une remarque. Le système ne récupère pas de suite la mémoire alors qu'avec l'autoreleasepool oui.


    La seule explication logique est, me semble t'il, que les méthodes alloc/initXXX de NSImage génèrent elles-même beaucoup d'objets (lourds) en autorelease, et que ces méthodes n'usent pas d'un autoreleasePool local. C'est mesquin de la part d'Apple...

    .
  • AliGatorAliGator Membre, Modérateur
    12:18 modifié #35
    dans 1136404141:

    dans 1136393672:

    Bon ça ne répond pas à  la question que j'ai posée à  SuperMic sur img2 : on envoie à  img2 les messages alloc/init puis release, dans la boucle while donnée en exemple. A chaque itération on gère nous-même l'alloc/init et le release, il n'y a pas d'autorelease qui intervient ici. img2 est donc bien releasée, et l'espace mémoire qu'il occupait est libéré. Et ce à  chaque itération dans la boucle. Donc je ne comprends pas pourquoi avec cette boucle tu dises que ça continue d'occuper 240 et qques Mo ???


    dans 1136400499:

    Je n'en sais pas plus. C'est juste une remarque. Le système ne récupère pas de suite la mémoire alors qu'avec l'autoreleasepool oui.


    La seule explication logique est, me semble t'il, que les méthodes alloc/initXXX de NSImage génèrent elles-même beaucoup d'objets (lourds) en autorelease, et que ces méthodes n'usent pas d'un autoreleasePool local. C'est mesquin de la part d'Apple...

    .
    En effet, c'est sûrement ça (bonne analyse, Bru :o) et très mesquin si c'est en effet ça >:(
    En tout cas bon à  savoir :-/

    Conclusion : vraiment rien de mieux qu'un autoreleasepool local :D
Connectez-vous ou Inscrivez-vous pour répondre.