Taille d'un objet en mémoire

UniXUniX Membre
21:22 modifié dans API AppKit #1
Salut.

J'ai à  priori un pb sur un objet dont la taille augmente anormalement ....
Je souhaiterais le monitorer pour voir à  quel moment il augmente. Existe t'il un moyen de voir sa taille en mémoire à  un moment donné de l'exécution ?

Réponses

  • schlumschlum Membre
    21:22 modifié #2
    La "taille" d'un objet est fixe ; c'est la taille de la structure équivalente à  ses variables d'instance.
  • UniXUniX Membre
    21:22 modifié #3
    OK, je me suis mal exprimé.

    Donc en fait, j'ai une des variables d'instance d'un objet qui augmente, et je voudrais en connaà®tre sa taille.
  • schlumschlum Membre
    21:22 modifié #4
    dans 1175165626:

    OK, je me suis mal exprimé.

    Donc en fait, j'ai une des variables d'instance d'un objet qui augmente, et je voudrais en connaà®tre sa taille.



    Euh... La remarque est la même pour les variables d'instance.
    Tout objet ou variable en C ou en Objective-C a une taille fixe.
    Après, une partie de cette variable ou de cet objet peut être un pointeur qui peut être nil / NULL ou pointer sur une autre variable ou un autre objet qui a lui même une taille.

    Tu veux peut-être dire que le nombre de références sur d'autres objets (en récursif) augmente ?
  • 21:22 modifié #5
    Je pense qu'il parle surtout de l'utilisation mémoire d'un objet type NSImage, NSData, éventuellement un gros NSString, etc... donc plus les données qu'il contient que l'object lui même...

    Ceci dit je ne sais pas comment faire. On peut coupler le terminal/debuger et visualiser l'augmentation/reduction mémoire lors du chargement/release d'un objet mais ce n'est pas précis (même si c'est plutôt fiable).
  • schlumschlum Membre
    21:22 modifié #6
    Il faut utiliser ObjectAlloc ou MallocDebug
    Mais bon, en général ce sont des structures genre liste chaà®nées etc. en pratique on ne voit pas grand chose à  part des allocations de blocs mémoire.
  • UniXUniX Membre
    21:22 modifié #7
    Oui, en fait j'ai un objet qui contient des strings, d'autres objets persos, et une NSImage.
    J'enregistre cet objet sur disque sous forme de fichier (il s'agit du fichier library de Discoway).

    Et je me suis aperçu que ce fichier, lors de l'import de certaines cartes, augmente énormement (3 ou 400 Mo alors qu'il ne devrait pas faire plus de 500 ou 600 ko ...), alors qu'il ne contient que des données peu "lourdes" ...

    J'aurais donc voulu monitorer à  quel moment dans le cycle d'importation il augmente.
    Ce que je vais faire, c'est rajouter à  divers endroits du cycle des enregistrement sur disque, et retourner en NSLog la taille du fichier.

  • schlumschlum Membre
    21:22 modifié #8
    Je parie que tu charges des cartes en format compressé (jpg, png, pdf...) et que tu les enregistres en bitmap (tiff) !
  • UniXUniX Membre
    21:22 modifié #9
    ;)

    Non, non, dans ce fichier, je n'y stoche pas les cartes, seulement les infos relatives à  la carte, et qui me servent à  remplir la tableView de gestion des cartes.
    Le seul truc qui est sucpsceptible de peser, c'est la NSImage, mais ce n'est que la vignette des cartes qui s'affiche dans Infos .... Donc une image riquiqui .....

    J'y suis dessus, je vais essayer de voir ce qui ne va pas .....
  • mars 2007 modifié #10
    dans 1175180043:

    Il faut utiliser ObjectAlloc ou MallocDebug
    Mais bon, en général ce sont des structures genre liste chaà®nées etc. en pratique on ne voit pas grand chose à  part des allocations de blocs mémoire.

    C'est pour ça que dans ce cas (utilisation mémoire assez notable) je parlais du terminal...

    dans 1175183693:

    Et je me suis aperçu que ce fichier, lors de l'import de certaines cartes, augmente énormement (3 ou 400 Mo alors qu'il ne devrait pas faire plus de 500 ou 600 ko ...), alors qu'il ne contient que des données peu lourdes ?

    Pourquoi ne pas placer des points d'arrêt afin d'analyser à  l'aide du debugeur et du terminal les importations un peu trop "lourdes" ?
  • UniXUniX Membre
    21:22 modifié #11
    C'est ce que je suis en train de faire.
    A priori, ça viendrait de mes vignettes qui sont anormalement pas si riquiqui que ça !
    Avec le terminal, tu pensais à  quoi ?
  • mars 2007 modifié #12
    Pardon... je n'avais pas précisé... Un "top" (ou "top 5"), colonne "RSIZE".

    T'es sur que les vignettes ne sont pas juste redimensionnée ?
  • schlumschlum Membre
    21:22 modifié #13
    dans 1175185606:

    C'est ce que je suis en train de faire.
    A priori, ça viendrait de mes vignettes qui sont anormalement pas si riquiqui que ça !
    Avec le terminal, tu pensais à  quoi ?


    Si tu veux comprimer tes vignettes ->

    - (NSData *)TIFFRepresentationUsingCompression:(NSTIFFCompression)comp factor:(float)aFloat
    


    Riquiqui ça veut dire quoi pour toi ? Tu sais que si tu enregistres en bitmap, ça donne du 4 octets par pixel... Ca monte vite !
  • UniXUniX Membre
    mars 2007 modifié #14
    Alors en fait je pars des images des cartes, qui font (dans les exemples que je suis en train d'étudier) aux alentours de 6000x6000 pixels. J'ai donc des NSImage de 6000x6000 pixels.

    Pour obtenir les vignettes, j'ai le code suivant :
    // détermination du coef de réduction à  appliquer pour obtenir une vignette max 130x120<br />NSAffineTransform *miseEchelle = [NSAffineTransform transform];<br />[miseEchelle scaleBy:coefZoom];<br />tailleImage = [miseEchelle transformSize:tailleImage];<br />NSImage *vignette = [[image copy]autorelease];<br />[vignette setScalesWhenResized:YES];<br />[vignette setSize:tailleImage];
    


    Là  j'ai donc réduit les images, et j'ai une vignette d'environ 130x120 (c'est vérifié).

    Ensuite, j'enregistre la vignette dans mon objet librairie en tant que NSImage. Mais théoriquement, même en bitmap, une image de 130x120, ça doit pas peser très lourd ....?

    Supermic, quand tu dis "T'es sur que les vignettes ne sont pas juste redimensionnée ?", je penses qu'elles sont justes redimensionnées effectivement, mais que veux tu y faire de plus ?
  • UniXUniX Membre
    21:22 modifié #15
    Je viens de vérifier, à  la fin de l'importation, le fichier library fait à  peut prêt la même taille que l'ensemble des cartes bitmap que j'ai importé...

    J'en déduis, que le fait de réduire la taille d'une NSImage avec setSize: ne réduit pas pour autant son poids ?
  • mars 2007 modifié #16
    Bein je te conseil de lire : http://forums.macfr.com/Creer-une-imagette-d-une-grande-image-t10514.html&hl=NSImage

    Fais des vignettes en 240x240, ça te donneras un peu de marge comme ça (la mode à  la haute definition en ce moment...) mais tout dépend de combien d'images sont stockées mais bon l'icône d'un fichier c'est déjà  du 128x128 alors toi tu peux pousser un peu dans la logique des choses mais c'est du détail.

    L'idéal aussi serait que ton fichier "library" sont en "bundle" (fichier plist + les images enregistrées en .png dans le dossier...) mais c'est également du détail...

    Pour l'enregistrement en PNG :

    NSBitmapImageRep *rep=[NSBitmapImageRep imageRepWithData:[bigImage TIFFRepresentation]];<br />NSData *PNGData=[rep representationUsingType:NSPNGFileType properties:nil];<br />NSImage *smallImage=[[NSImage alloc] initWithData:PNGData];<br />
    

  • UniXUniX Membre
    21:22 modifié #17
    Oui, j'ai en prévision de faire tout ce que tu as indiqué Supermic .... Il faut que je trouve le temps ....


    Bon, j'ai résolu ce pb de fichier library qui grossissait à  vu d'oeil.
    Après avoir réduit la taille d'une image avec setSize:, il faut également l'écrire dans une autre image, afin de diminuer son poids.
    :adios!:

    Si un modérateur passe par ici, il serait peut être bon de scinder ce sujet en 2. On est parti sur le poids d'un objet, et fini sur des réductions d'images. Merci.
  • BruBru Membre
    21:22 modifié #18
    dans 1175190169:

    Après avoir réduit la taille d'une image avec setSize:, il faut également l'écrire dans une autre image, afin de diminuer son poids.


    setSize: ne réduit en aucun cas l'image elle même, mais juste son "espace" d'affichage.
    C'est pourquoi son poids reste le même, mais aussi pourquoi tu as galéré pour faire une réduction "jolie" (avec flou).

    Normalement, un code "propre" de réduction d'image avec floutage devrait être comme suivant :
    <br />NSImage* PetiteImage(NSImage *grandeImage)<br />{<br />&nbsp;  NSImage *petiteImage;<br />&nbsp;  NSRect petitRect, grandRect;<br /><br />&nbsp;  // taille de la petite image<br />&nbsp;  petitRect.origin=NSZeroPoint;<br />&nbsp;  petitRect.size=NSMakeSize(200, 200);<br /><br />&nbsp;  // création de la petite image<br />&nbsp;  petiteImage=[[NSImage alloc] initWithSize:petitRect.size];<br /><br />&nbsp;  // ouverture du port graphique de la petite image<br />&nbsp;  [petiteImage lockFocus];<br />&nbsp;  [NSGraphicsContext saveGraphicsState];<br /><br />&nbsp;  // récupération de la taille de la grande image<br />&nbsp;  grandRect.origin=NSZeroPoint;<br />&nbsp;  grandRect.size=[grandeImage size];<br /><br />&nbsp;  // modif du port graphique<br />&nbsp;  [[NSGraphicsContext currentContext] setImageInterpolation:NSImageInterpolationHigh];<br />&nbsp;  [[NSGraphicsContext currentContext] setShouldAntialias:YES];<br /><br />&nbsp;  // dessin de la grande image dans la petite<br />&nbsp;  [grandeImage drawInRect:petitRect fromRect:grandRect operation:NSCompositeCopy fraction:1.0];<br /><br />&nbsp;  // fermeture du port graphique de la petite image<br />&nbsp;  [NSGraphicsContext restoreGraphicsState];<br />&nbsp;  [petiteImage unlockFocus];<br /><br />&nbsp;  return [petiteImage autorelease];<br />}<br />
    


    .
  • UniXUniX Membre
    mars 2007 modifié #19
    2ème  :adios!: :adios!: :adios!: de la soirée ....!

    J'étais arrivé à  avoir un code presque similaire, sauf que je faisais un setSize: sur la grande image, et que je n'avais pas mis le setShouldAntiAlias: (j'avoue ne pas avoir pensé que ça pouvais avoir un effet sur les images ... :().

    Et le problème d'image mal redimensionnée, envolé !!!!!
    Merci beaucoup Bru pour ect éclaircissement.

    Schlum, tu vas pouvoir utiliser ça dans SudokuX également !
  • schlumschlum Membre
    21:22 modifié #20
    dans 1175196078:

    2ème  :adios!: :adios!: :adios!: de la soirée ....!

    J'étais arrivé à  avoir un code presque similaire, sauf que je faisais un setSize: sur la grande image, et que je n'avais pas mis le setShouldAntiAlias: (j'avoue ne pas avoir pensé que ça pouvais avoir un effet sur les images ... :().

    Et le problème d'image mal redimensionnée, envolé !!!!!
    Merci beaucoup Bru pour ect éclaircissement.

    Schlum, tu vas pouvoir utiliser ça dans SudokuX également !


    Bah j'aime bien ma méthode... Et je crée aussi le handle pour l'icône document en même temps...
  • mars 2007 modifié #21
    La magie de Bru c'est que non seulement il répond directement à  l'une de tes questions mais qu'en plus la formulation de son message indique indirectement la réponse d'un tout autre problème qui lui n'est pas encore apparu...
  • 21:22 modifié #22
    Je me permet de remonter le sujet car j'ai un problème sur une image de 1400x1400 px
    Lorsque je resize à  500x500, c'est vraiment trop trop précis au point d'être moche. Apparemment l'antialiasing ne marche pas car que je mette no ou yes ça ne change rien sur mon image.
    Pareil pour l'interpolation.

    Voici mon code :

    <br />NSImage *petiteImage;<br />&nbsp;  NSRect petitRect, grandRect;<br /><br />&nbsp;  // taille de la petite image<br />&nbsp;  petitRect.origin=NSZeroPoint;<br />&nbsp;  petitRect.size=newSize;<br /><br />&nbsp;  // création de la petite image<br />&nbsp;  petiteImage=[[NSImage alloc] initWithSize:petitRect.size];<br /><br />&nbsp;  // ouverture du port graphique de la petite image<br />&nbsp;  [petiteImage lockFocus];<br />&nbsp;  [NSGraphicsContext saveGraphicsState];<br /><br />&nbsp;  // récupération de la taille de la grande image<br />&nbsp;  grandRect.origin=NSZeroPoint;<br />&nbsp;  grandRect.size=[image size];<br />	<br />&nbsp;  // modif du port graphique<br />&nbsp;  [[NSGraphicsContext currentContext] setImageInterpolation:NSImageInterpolationLow];<br />&nbsp;  [[NSGraphicsContext currentContext] setShouldAntialias:YES];<br /><br />&nbsp;  // dessin de la grande image dans la petite<br />&nbsp;  [image drawInRect:petitRect fromRect:grandRect operation:NSCompositeCopy fraction:1.0];<br /><br />&nbsp;  // fermeture du port graphique de la petite image<br />&nbsp;  [NSGraphicsContext restoreGraphicsState];<br />&nbsp;  [petiteImage unlockFocus];<br />
    


    Qui est le même que celui de Bru..

    Après je sauvegarde l'image comme ceci :
    <br />imageData = [petiteImage TIFFRepresentation];<br />	imageRep = [NSBitmapImageRep imageRepWithData:imageData];<br />imageData = [imageRep representationUsingType:NSJPEGFileType properties:nil];<br />[imageData writeToFile:path atomically:NO];<br />[petiteImage release];<br />
    
  • UniXUniX Membre
    21:22 modifié #23
    dans 1187722581:

    [[NSGraphicsContext currentContext] setImageInterpolation:NSImageInterpolationLow];
    



    NSImageInterpolationHigh ?

    Pour moi ce code marche nickel ....
  • 21:22 modifié #24
    dans 1187726439:

    dans 1187722581:

    [[NSGraphicsContext currentContext] setImageInterpolation:NSImageInterpolationLow];
    



    NSImageInterpolationHigh ?

    Pour moi ce code marche nickel ....


    Oops pardon, non c'est parce que j'avais testé le changement de l'interpolation, et que je mette low ou high ça ne change rien non plus...

  • schlumschlum Membre
    21:22 modifié #25
    Reste mon code  :P (passer soi même en dur un filtre de moyennes)
  • UniXUniX Membre
    21:22 modifié #26
    Pourtant ce code marche parfaitement ..... Je l'utilise avec succès dans mon appli !

    Essayes peut être d'afficher l'image dans une NSImageView plutôt que de l'enregistrer sur le disque, pour vérifier que le pb n'est pas lors de l'enregistrement (on sait jamais ...).
  • 21:22 modifié #27
    Alors bizarrement si je fais un setSize: sur la grande image, là  j'ai plus de pixels dégeulasses sur l'image finale...
    Mais NSGraphicsContext ne veut toujours pas marcher (même sans l'enregistrement)
Connectez-vous ou Inscrivez-vous pour répondre.