Core Image et fuites mémoires
Mala
Membre, Modérateur
Histoire de donner suite à la question de Chacha lorsque j'évoquais des fuites mémoires sur un autre sujet, voici ce que j'ai constaté en utilisant Core Image.
Je travaille actuellement sur une appli qui doit appliquer des filtres Core Image à une série d'images. Seulement voilà , s'agissant de traitements en arrière plan, je suis amené à retransformées mes CIImage en NSImage pour une sauvegarde sur le disque. A cette occasion j'ai constaté de grosses fuites sur mon iMac 24". J'ai d'abord pensé à un problème perso oui mais voilà , le même test sur le mac book ne pose aucun problème de fuites!
La création d'une NSImage (une vraie. Pas un une NSImage like encapsulant une CIImage) nécessite la création d'une représentation bitmap puis je viens associer ma représentation à un contexte. Un bout de code dans le genre:
nsContext = [NSGraphicsContext graphicsContextWithBitmapImageRep:bitmapImageRep];
Le hic, c'est que la représentation liée au contexte ne semble jamais libérée par la suite (comme si sur l'iMac le NSGraphicContext ne la libérait pas lorsque on le supprime). Et comme je suis amené à créer des représentations pour toutes les images, je vous raconte pas l'explosion mémoire. :crackboom:-
La question que je me pose à ce stade c'est: est-ce que le Mac Book et sa petite GMA 950 ne ferait pas les calculs au niveau CPU et non GPU. Cela pourrait expliquer la différence de comportement du fait de l'aiguillage vers la GPU sur l'iMac et pas sur le Mac Book.
J'ai fait quelques recherches sur le Net et il semble bien y avoir des problèmes liés au contexte graphique employé.
Le phénomène est présent dans les codes d'exemple d'apple et plus particulièrement l'exemple "Reducer"
http://developer.apple.com/samplecode/Reducer/
Sur le MacBook pas de problème mais sur l'iMac 24" j'explose la mémoire en jouant quelques secondes avec le slider Radius ou Intensity par exemple.
On trouve d'ailleurs une référence à cette exemple sur la quartz-dev liste d'Apple...
http://lists.apple.com/archives/quartz-dev/2006/Dec/msg00035.html
Je cite un bout de la discussion
Pour les anglophobes :P , en clair il semblerait que dès qu'on utilise un autre contexte que les contextes existants on s'expose à des fuites.
Les solutions évoquées sont d'utiliser le contexte de l'écran ou bien de dessiner dans le context courant. Je trouve ça bancale. A mon sens, on ne fait que contourner grossièrement le problème. Quiz de l'application de filtres en parallèle et qui utiliseraient le même contexte de rendu? Que ce passe-t-il si la représentation bitmap associée au contexte change (une nouvelle image avec des dimensions différentes par exemple)?
Pour le moment, la seule solution fiable (si l'on peut dire) que j'ai trouvé consiste à créer le contexte et sa représentation associée au premier appel de ma méthode de conversion. Ensuite, je les conserve pour les autres images à traiter. Si les caractéristiques d'une nouvelle image change alors j'ai éventuellement une fuite car je viens recréer la représentation. Comme la plupart du temps le flux provient d'une même source (vidéo, apn, ou autre) la représentation et son contexte ne sont pas recréés et la fuite est "maà®trisée". Enfin, je retourne une copie de ma NSImage afin de dupliquer la représentation et d'éviter tout écrasement car mes traitements sont multi-threadés :brule: (le filtrage et l'écriture des fichiers sont réalisés par deux threads distincts).
Je n'ai pas trouvé de solution magique. Je me demande d'ailleurs si le problème ne serait pas lié à l'implémentation de la version d'OpenGL actuelle. Léopard pourrait alors peut-être y apporter une solution (j'espère ).
Si vous avez des idées, je suis preneur de toute suggestion.
Mala.
Je travaille actuellement sur une appli qui doit appliquer des filtres Core Image à une série d'images. Seulement voilà , s'agissant de traitements en arrière plan, je suis amené à retransformées mes CIImage en NSImage pour une sauvegarde sur le disque. A cette occasion j'ai constaté de grosses fuites sur mon iMac 24". J'ai d'abord pensé à un problème perso oui mais voilà , le même test sur le mac book ne pose aucun problème de fuites!
La création d'une NSImage (une vraie. Pas un une NSImage like encapsulant une CIImage) nécessite la création d'une représentation bitmap puis je viens associer ma représentation à un contexte. Un bout de code dans le genre:
nsContext = [NSGraphicsContext graphicsContextWithBitmapImageRep:bitmapImageRep];
Le hic, c'est que la représentation liée au contexte ne semble jamais libérée par la suite (comme si sur l'iMac le NSGraphicContext ne la libérait pas lorsque on le supprime). Et comme je suis amené à créer des représentations pour toutes les images, je vous raconte pas l'explosion mémoire. :crackboom:-
La question que je me pose à ce stade c'est: est-ce que le Mac Book et sa petite GMA 950 ne ferait pas les calculs au niveau CPU et non GPU. Cela pourrait expliquer la différence de comportement du fait de l'aiguillage vers la GPU sur l'iMac et pas sur le Mac Book.
J'ai fait quelques recherches sur le Net et il semble bien y avoir des problèmes liés au contexte graphique employé.
Le phénomène est présent dans les codes d'exemple d'apple et plus particulièrement l'exemple "Reducer"
http://developer.apple.com/samplecode/Reducer/
Sur le MacBook pas de problème mais sur l'iMac 24" j'explose la mémoire en jouant quelques secondes avec le slider Radius ou Intensity par exemple.
On trouve d'ailleurs une référence à cette exemple sur la quartz-dev liste d'Apple...
http://lists.apple.com/archives/quartz-dev/2006/Dec/msg00035.html
Je cite un bout de la discussion
Dave: if the current OpenGL context is not the one drawImage: wants to use. It seems to create a temporary OpenGL context, and then doesn't clean up after it, or something.
Will: The only solution I've found is to use the screen's context, I guess this is because it is the only method that does not create a temporary OpenGL context.
Pour les anglophobes :P , en clair il semblerait que dès qu'on utilise un autre contexte que les contextes existants on s'expose à des fuites.
Les solutions évoquées sont d'utiliser le contexte de l'écran ou bien de dessiner dans le context courant. Je trouve ça bancale. A mon sens, on ne fait que contourner grossièrement le problème. Quiz de l'application de filtres en parallèle et qui utiliseraient le même contexte de rendu? Que ce passe-t-il si la représentation bitmap associée au contexte change (une nouvelle image avec des dimensions différentes par exemple)?
Pour le moment, la seule solution fiable (si l'on peut dire) que j'ai trouvé consiste à créer le contexte et sa représentation associée au premier appel de ma méthode de conversion. Ensuite, je les conserve pour les autres images à traiter. Si les caractéristiques d'une nouvelle image change alors j'ai éventuellement une fuite car je viens recréer la représentation. Comme la plupart du temps le flux provient d'une même source (vidéo, apn, ou autre) la représentation et son contexte ne sont pas recréés et la fuite est "maà®trisée". Enfin, je retourne une copie de ma NSImage afin de dupliquer la représentation et d'éviter tout écrasement car mes traitements sont multi-threadés :brule: (le filtrage et l'écriture des fichiers sont réalisés par deux threads distincts).
Je n'ai pas trouvé de solution magique. Je me demande d'ailleurs si le problème ne serait pas lié à l'implémentation de la version d'OpenGL actuelle. Léopard pourrait alors peut-être y apporter une solution (j'espère ).
Si vous avez des idées, je suis preneur de toute suggestion.
Mala.
Connectez-vous ou Inscrivez-vous pour répondre.