Limitation de mémoire pour images entre 600lo et 2mo - Java - Programmation
Marsh Posté le 28-08-2006 à 16:13:35
Fais une inspection de ton code, tu dois avoir des objets qui sont référencés et qui ne sont peuvent pas être éliminés par le GC.
Marsh Posté le 28-08-2006 à 20:17:06
et bien, je force meme le GC... en utilisant *.finalise()... et les contexte graphiques je les supprime avec *.dispose().. c'est assez propre comme code (pour une fois)... j'ai meme une erreur de dépassement de memoire en ne faisant que : ouvrir un JPG, puis enregistrer sous TIFF, j'utilise JAI car ca a l'air pratique pour le chagement de format.
Marsh Posté le 28-08-2006 à 20:18:49
Je me demande si ce n'est pas jBuilder qui contrain les capacités et les inscrits dans le fichier JAR que je crée pour la diffusion. Mais, les fichiers JAR, je ne maitrise pas trop.
Marsh Posté le 28-08-2006 à 20:29:44
Mais si tes objets sont tjrs référencés, le GC ne les collectera pas, même en le forçant et tu as un memory leak. Il faut mettre leurs références à null.
Lis ces articles:
http://www-128.ibm.com/developerwo [...] index.html
http://www-128.ibm.com/developerwo [...] 01246.html
Des Heap profilers peuvent t'aider à localiser le pb, comme http://appperfect.com/support/tuto [...] _leak.html
Marsh Posté le 28-08-2006 à 20:36:09
ok, J'ai mis à null un maximum de références, pas toutes, je vais essayer ce que tu dis el muchado. merci.
Marsh Posté le 28-08-2006 à 20:48:01
Ok, dis-nous ce qu'il en devient. Et n'abuse pas des null non plus. Mieux vaut comprendre ce qui cause le leak.
Marsh Posté le 28-08-2006 à 22:30:18
bon... merci à tous. En fait, j'avais un dépassement de tableau de 1 qui état intercepté, le processus continuait, et là, ca explosait car les variables n'étaient plus définies. C'est une erreur qui m'arrive souvent, je l'ai tracée avec de nombre System.out.printn("la il se passe..." + var). Ce qui est bizarre, c'est que ce soit la mémoire qui soit mise en cause et pas simplement le dépassement... Merci à tous. J'ai exploré tes liens el muchacho, mais... j'ai relu mon code avant de m'engager dans un nouvel outil. Merci mille fois. Ca marche maintenant. tenez, en cadeaux, un petit logiciel pour faire des dessins animés. envoyez moi un mail et je vous le passe.
Marsh Posté le 28-08-2006 à 22:53:14
En fait, ca ne marche pas non plus, j'avais une variable de réduction de l'image qui résolvait le probleme. donc, il va falloir que je bricole avec les leak.. grrrrrrrr
Marsh Posté le 28-08-2006 à 23:04:01
Tu peux commencer par mettre des
Code :
|
à certains endroits du code pour voir comment l'occupation mémoire augmente, afin de cerner la portion de code en cause.
Marsh Posté le 30-08-2006 à 08:55:27
L'erreur arrive, comme je m'en doutais au moment ou je créé un tableau int[9000000] correspondant à l'image RGB à traiter (3000x3000pixels).
En réduisant à 1000x1000 ca passe. mais une image de cette taille là, cela ne correspond plus au cahier des charges. je suis vraiment bloqué : je me dis que java est peut-etre limité pour le traitement des images... En cherchant, Photoshop traite avec un espace HD tampon. c'est peut-etre ce que je vais faire, mais ca va allourdir considérablement le programme. D'un autre côté, la capacité mémoire ne sera plus un problème... un avis ?
Marsh Posté le 30-08-2006 à 09:21:02
Tu es sûr que c'est au moment de l'allocation de ton tableau que ça plante ? et que dit l'état de la mémoire juste avant. Car ce tableau me parait pas énorme ...
Marsh Posté le 30-08-2006 à 21:31:08
cocos2000 a écrit : L'erreur arrive, comme je m'en doutais au moment ou je créé un tableau int[9000000] correspondant à l'image RGB à traiter (3000x3000pixels). |
Ah ben d'accord, tu aurais pu le dire plus tôt.
Du traitement d'images de cette taille-là, ça se fait tjrs par pavés de 500x500. C'est ce que font les logiciels de traitement d'image un peu sérieux. Tu ne pourras jamais faire du traitement sérieux avcec des images 3000x3000 chargées en RAM. C'est pas scalable, ta solution. Dès qu'on voudra mettre qqs filtres, tu vas faire péter la Heap.
Et oui, ça nécessite de concevoir tous les algos (et même un thread de calcul adhoc) de façon à ce qu'ils traitent par pavés, avec enregistrement sur disque au cours du calcul et éventuellement possibilité d'annuler en cours. Donc si on t'a demandé de faire ça, il faut prévoir le temps de développement qui va avec, parce qu'il n'y a pas d'autre solution (je le sais d'autant mieux que j'ai travaillé sur un tel logiciel. On pouvait faire du 10000x15000.)
Marsh Posté le 30-08-2006 à 21:52:21
3000 * 3000 * 4octets ça ne fait que 36meg et ça passe très bien.
Marsh Posté le 31-08-2006 à 01:01:38
merci el muchado, ce son de tres bons conseils, peut-etre pourrions nous voir cela ensemble... je ne suis que paysagiste et pas vraiment programmateur, donc, cela dépasse un peu mes compétences. MAis j'ia le temps.... si cela t'interesse dis le moi je t'en dirai bien plus.
Marsh Posté le 31-08-2006 à 02:01:34
cocos > l'allocateur n'arrive pas à allouer un objet de cette taille à cause de la fragmentation de la mémoire (je rentre pas dans les détails).
tu peux tenter une feinte de l'ours en découpant ton tableau de pixels comme ça (sauf que je sais plus utiliser les arrays à plusieurs dimensions) :
Code :
|
ce qui fait que la mémoire aura a chercher 100 places de 90000*4 octets de long plutôt qu'une seule place de 36Mo d'un coup.
Marsh Posté le 31-08-2006 à 19:57:30
merci nRaynaud, ca a l'air simple comme mise en place. J'essaie.
Marsh Posté le 31-08-2006 à 20:32:28
nRaynaud, j'ai codé ce que tu me dis, mais en fait, il me mets toujours la meme erreur... Je vais tenter le conseil de elMuchado.
Taz, comment fais-tu pour que ca passe ? tu as 3to de mémoire ?
Marsh Posté le 31-08-2006 à 20:34:31
elMuchado, je me demande un truc... j'arrive bien a charger une image de 3000x3000 pixel. comment se fait-il que la transformation en Integer ne se passe pas...
Marsh Posté le 31-08-2006 à 20:41:30
pour Bobuse : voila ce que ca marque
> mémoire libre : 15423544
> tableau de calcul : int[9000000]
java.lang.OutOfMemoryError
les lignes commencant par ">" sont des formules calcullées avec ">memoire " + Runtime.getRuntime().freeMemory()" ou similaire
Marsh Posté le 31-08-2006 à 20:44:21
cocos > ton -Xmx est à combien ?
Marsh Posté le 31-08-2006 à 20:50:33
Voici ce que ca doit faire (pour une image de taille réduite):
image initiale : image finale :
Marsh Posté le 31-08-2006 à 20:53:09
nRaynaud, mon -Xmx est à 400mo, je n'ai que 512 de ram.. donc je laisse quelques méga pour windows... je n'ai pas essayé de bloqué au max.
Marsh Posté le 31-08-2006 à 21:12:08
bon, je désespere. Ca marche avec une image de 1700 x 1700 pix..
on va s'arreter là, je ne sais pas faire. voila la différence entre un VRAI programmeur et un programmeur du dimanche ...
Marsh Posté le 31-08-2006 à 22:25:47
coco > tente de fragmenter plus, genre
int heap[][] = new int[1000][9000];
Marsh Posté le 31-08-2006 à 23:10:22
nRaynaud... non, ca ne marche vraiment pas. En fait, au début je fragmentait l'image comme ca sans le savoir. Maintenant, elle n'est plus fragmentée...
Marsh Posté le 01-09-2006 à 03:29:18
cocos2000 a écrit : Voici ce que ca doit faire (pour une image de taille réduite): |
c'est la fameuse transformation de Goatse, ton algo?
Marsh Posté le 01-09-2006 à 07:51:54
nan, s'il est paysagiste, il doit prendre une foto de son jardin avec un fisheye tourné vers le haut et il essaye de transformer en clindrique après, probablement pour quicktime VR.
Marsh Posté le 01-09-2006 à 07:53:21
cocos2000 a écrit : elMuchado, je me demande un truc... j'arrive bien a charger une image de 3000x3000 pixel. comment se fait-il que la transformation en Integer ne se passe pas... |
Honnêtement, je ne sais pas. Ce qui est certains, c'est que tu crées 9 000 000 d'objets d'un coup, et il se peut que ça fragmente la mémoire, même si j'en doute parce que les GC sophistiqués gèrent cela très bien.
Citation : bon, je désespere. Ca marche avec une image de 1700 x 1700 pix.. |
N'abandonne pas, c'est pas forcément facile, mais c'est un challenge intéressant. Ceci dit, on n'a pas forcément de réponse toute prête. Essaye de faire comme je t'ai dit sur une image 100x100 que tu divises en pavés de 50x50, avec des traitements simples qui fonctionnnent par pavé.
Marsh Posté le 01-09-2006 à 10:17:51
ReplyMarsh Posté le 01-09-2006 à 12:46:56
el muchacho a écrit : N'abandonne pas, c'est pas forcément facile, mais c'est un challenge intéressant. |
euh
Marsh Posté le 01-09-2006 à 15:29:53
cocos2000 a écrit : Taz, comment fais-tu pour que ca passe ? tu as 3to de mémoire ? |
rien de spécial mais ça passe. Colle ton -Xmx à donf. Je ne sais pas comment fait Sun java, mais si mx est une taille de mémoire virtuelle, alors tu peux très vite y monter.
Tu peux peut-être jouer avec -verbose:gc voir ce qui se passe avant ton plantage ?
Marsh Posté le 01-09-2006 à 23:52:57
bobuse a écrit : Ou peut-être qu'il faut changer de langage |
Non, je dirais qu'à priori il n'y a aucune raison. Il vaudrait mieux qu'il nous donne un bout de code (la structure des données après lecture de l'image et l'algo de traitement qui fait péter) et qu'il fasse un profilage de la Heap pour voir ce qui cloche, parce qu'il y a clairement qq chose qui cloche.
Taz> 3000x3000 ça fait 36 Mo, mais 5000x5000 ça en fait tout de suite 100. Après, faut voir si il a besoin d'autant.
cocos2000> D'ailleurs je vois que JAI implémente le traitement d'images par pavés "Tiles", avec des opérateurs simples sur les images que l'on peut combiner dans un pipeline, comme il convient de faire.
A mon avis, tu devrais essayer de suivre le tutorial sur l'utilisation de JAI, tu ne l'utilises pas correctement, à l'évidence. Et cette API est visiblement compliquée à utiliser correctement. Tu ne devrais pas avoir à traiter des images 3000x3000 d'un seul bloc.
Autre tutoriel bien foutu: http://www.inf.ufrgs.br/~revista/d [...] utorial%22
Marsh Posté le 02-09-2006 à 13:00:27
bon... je vais vous dire à quoi ca sert : il s'agit, à partir d'une image fisheye, prise verticalement - bien vu. Ce n'est pas de faire un QuickTime VR, il ya des programmes pour ca. Il s'agit juste de faire cette transformation, d'enregister l'image et de la caller dans un Système d'information géographique, à la coordonnée du point de vue, repéré par GPS. Comme ca, on a on la carte au centre, et tout ce que l'on voit depuis ce point la.
Marsh Posté le 02-09-2006 à 16:27:06
J'ai rien compris.
Quel est l'intérêt d'une image complètement déformée par rapport à un panoramique de photos ? Et cette histoire de carte au centre, de GIS avec des photos distordues (parce que vu le taux de distortion, je doute qu'on puisse un jour arriver à qq chose de potable, d'ailleurs, l'exemple au-dessus est assez significatif, c'est à peine lisible), etc.
Bref...
Marsh Posté le 03-09-2006 à 11:05:05
Ok... c'est un peu comme une image d'échographie... on ne comprend pas grand chose quand on la regarde comme une image "normale". ... pas de problème !!
Merci en tous cas a vous de l'aide et des conseils. Je vais aviser et peut etre sollicité la cellule informatique de la boite. ils doivent avoir une idée pour faire ca.
Marsh Posté le 16-09-2006 à 19:47:31
Bon... ca y est, ca marche. j'ai revu tout le code. Il y avait une redondance entre 2 images bufferisées, et un fichier en mémoire. Ca marche donc jusqu'à une certaine taille, qui me suffit (3000x3000pix).
Reste un problème : comment configurer la JVM dans un JAR pour passer par exemple les paramètres -Xms et -Xmx ?
Marsh Posté le 16-09-2006 à 22:50:25
tu peux pas, vu que .class ou .jar, tu lances toujours 'java ... machin'. Livre un script avec
Marsh Posté le 27-08-2006 à 22:54:36
Bonjour, je fais une application pour manipuler des images sphériques au format jpg... J'utilise JAI entre autre... J'ai un problème de mémoire dès que je veux faire des opérations sur une image de plus de 600ko. Pourtant, j'ai paramétrer la JVM avec -Xms128mo et -Xmx 256mo, ce qui est largement surdimensionné à prirori.
Le message d'erreur est clair : Java.lang.OutOfMemory
Que faire ??
sinon, le système c'est : WindowsXP sp2, Jbuilder9.0, 512mo de ram...
Merci beaucoup.