2010-04-16 3 views
0

Notre système utilise beaucoup de grandes bitmaps (System.Drawing.Bitmap) et parfois nous manquons de mémoire et obtient une erreur "Parameter is not valid". Cela a du sens, car il peut être difficile d'allouer un gros morceau de mémoire continu.GDI + sur les systèmes 64 bits

Donc la question est ... Si nous avons mis à jour le système en 64 bits, ce problème disparaîtrait-il?

+0

De quelle taille parlons-nous? Etes-vous sûr que l'erreur "Parameter is not valid" est due à l'insuffisance de mémoire? –

+0

Hi musicfreak Les bitmaps peuvent facilement être 5000 x 5000. Je peux reproduire l'erreur dans – LaZe

+0

Pouvez-vous nous dire pourquoi il s'agit d'une question de type C#? Vous venez d'ouvrir les bitmaps dans une application de visualisation ou êtes-vous développer du code avec des bitmaps ou ouvrez-vous bitmaps dans visuel studio ...? –

Répondre

3

Si c'est un problème d'allocation de mémoire (en raison de la fragmentation de votre tas d'objets volumineux, il est tout à fait concevable que vous auriez des difficultés à allouer des morceaux de 100MB après quelque 20 images ont été chargées, même si certains d'entre eux ont par la suite été déchargé), puis passer à 64 bits devrait aider - l'espace d'adressage beaucoup plus large devrait donner beaucoup de place au tas pour travailler, et ainsi soulager les symptômes.

Un problème de mémoire doit produire une exception OutOfMemoryException, mais il est possible que le code de gestion de bitmap dans .net l'attrape et convertisse efficacement en une exception InvalidParameterException. Cependant, il y a une possibilité qu'il y ait un autre problème concernant la taille/format des images, et c'est vraiment un paramètre invalide.

+1

I ju st testet sur un système 64 bits, et a été capable de créer 6 bitmaps de 20000x20000 pixels chacun. (~ 1,5 Go par image) Ceci est loin d'être possible sur le système 32 bits. – LaZe

0

Il y a quelque temps, j'ai souvent rencontré ce type d'erreur lors du développement de Visual Studio 2008 sur un système Vista 64 bits. Donc, je suppose que passer à 64Bit peut augmenter les chances de succès et faire en sorte que l'erreur se produise moins souvent, mais je ne supposerais pas que le passage à 64 bits le guérira entièrement.

Ce qui m'a aidé a ce lien: http://confluence.jetbrains.net/display/ReSharper/OutOfMemoryException+Fix

Il est une enveloppe qui remplace la politique d'allocation de mémoire, S.T. vous avez tendance à obtenir des fragments de mémoire continue plus importants. Peut-être que vous pouvez également utiliser une politique d'allocation de mémoire similaire dans votre application, car celle-ci était supposée n'emballer que Visual Studio.

0

Il existe une limite quant à la taille d'un bitmap que vous pouvez créer sur un système.

Découvrez http://www.efg2.com/Lab/Graphics/VeryLargeBitmap.htm pour un programme qui peut vous montrer la limite du système.

Peut-être que vous atteignez cette limite.

0

Avant d'allouer ces gros bitmaps, vous pouvez essayer d'appeler GC.Collect(). J'ai eu exactement ce problème récemment, et cela m'a aidé. (Ma première réaction était aussi de passer en 64 bits, mais ajouter une ligne de code était un peu plus simple. ;-)

+0

Salut, j'ai fait ça, et ça m'a aidé ... mais le problème est revenu quand même. – LaZe

1

En général, quand vous commencez à jouer avec un énorme bitmap en mémoire, vous obtenez toujours ce genre de problème. La meilleure façon d'éviter cela est de diviser votre image dans un tableau ou quelque chose de similaire afin que vous puissiez créer une grille. À partir de ce moment-là, vous avez seulement besoin de charger à l'écran ce qui peut être visualisé, ce qui permettrait d'économiser beaucoup de mémoire.

Je me suis retrouvé avec ça quand j'ai décidé de créer un petit jeu pour tuer quelques fois.

J'ai décidé de créer un jeu Maze/Pipe et l'utilisateur pourrait choisir le nombre de colonnes et de lignes. J'ai décidé de limiter l'image à 10000px par 10000px.

Mon premier essai, j'avais exactement votre problème. erreur après erreur après erreur, principalement problème de mémoire.

J'ai décidé de faire des recherches sur comment faire ce que je voulais et j'ai trouvé la solution.Ce que j'ai fait, c'est que j'ai créé un tableau 2D dynamique (j'ai décidé de le limiter à un maximum de 1000 par 1000) et je leur ai juste ajouté une petite image de 10x10 pixels ou tout ce que l'utilisateur décide. Quand cela a été fait, le problème avec la mémoire/vitesse de chargement/etc ... était tout simplement parti.

utilisation de la mémoire avant que mon fix était facilement sur un concert, maintenant l'utilisation de la mémoire des applications est comprise entre 150 et 225 megs de RAM lorsque vous utilisez la limite

si vous voulez l'essayer, téléchargez cela et aller chercher dans le menu (Maze) et jouer avec le réglage:

1

Selon la façon dont Bitmap est créé, que ce soit DDB ou une mémoire vidéo DIB ou une mémoire système est utilisée (mémoire vidéo d'utilisation de DDB, mémoire système du DIB). Vous devrez utiliser DotNet reflector pour déterminer quand chacun est créé en fonction du constructeur que vous utilisez ... Par exemple, un DDB est créé lorsque vous allez:

var bmp = new Bitmap(width, height, pixelDepth) 

et cela peut avoir une limite de taille de 5000x5000 sur une machine avec une petite carte vidéo (à savoir les serveurs sur lesquels vous pourriez exécuter un webservice), alors que vous pouvez constater que vous pouvez charger une image bitmap 10000x10000 avec

var bmp = new Bitmap(pathToLargeFilename); 

Je n'ai pas eu beaucoup de chance de trouver comment la création de force de DIB in Dotnet (ma conjecture est la manière la plus simple serait la création manuelle de la structure Bitmap, l'allocation manuelle de la mémoire, puis en quelque sorte le lancer comme un bitmap. Ou peut-être votre meilleur pari est de passer à une autre bibliothèque d'imagerie qui n'utilise pas la mémoire vidéo (il y en a un certain nombre open source FreeImage, ImageMagick, Cairo (mais vous devrez au moins obtenir le GTK packages de Mono pour cela pour exécuter)

+0

Merci pour le conseil. Il semble utiliser GdipCreateBitmapFromScan0, donc je suppose qu'il utilise la mémoire système. – LaZe

+0

Cela crée une image bitmap à partir d'une image bitmap précédente (Scan0), de sorte que le bitmap a été créé à l'endroit où la mémoire est allouée. –

Questions connexes