7
votes

Le clone d'objet jetable va-t-il causer une fuite de mémoire dans C #?

Vérifiez ce code: xxx pré>

bitmap code> est iclonable code>, Idisposable code> in c #. p >

Trop éviter une fuite de mémoire, pour un objet jetable, utilisez normalement à l'aide de code>, puis l'objet sera disposé automatiquement par le système, peu importe la vitesse de votre code. P>

dans mon Échantillon, je ne peux pas utiliser en utilisant code> car je ne veux pas lancer l'objet, j'en ai besoin plus tard (la classe entière se disposera de son Idisposable code>. P >

Ma question est la suivante: j'ai un objet imageObject code>, puis je l'utilise clone () code> méthode clone un nouvel objet et donnez-le à la variable d'objet ancienne. Cela cause une (l'objet cloné ou original) ira nulle part et ne jamais être disposé, une fuite de mémoire. P>

[EDIT] P>

semble la plupart des opinions sont clone code> provoquent un objet supplémentaire, l'ancien doit être Disposer () code> p>

Voici le nouveau code: P>

    public void ImageCrop(int X, int Y, int W, int H)
    {
            // We have 1 object: imageObject
            using (Bitmap croppedImage = imageObject.Clone(new Rectangle(X, Y, W, H), imageObject.PixelFormat))
            {
                    // We have 2 objects: imageObject and croppedImage
                    imageObject.Dispose(); // kill one, only croppedImage left
                    imageObject = new Bitmap(croppedImage); // create one, now 2 objects again
            } // the using() will kill the croppedImage after this
            // We have 1 object: imageObject
    }


1 commentaires

Pourquoi la copie-tu deux fois?


6 Réponses :


2
votes

en utilisant juste des appels jetez dans un enfin bloc.
Tant que vous appelez jetez quelque part dans tous les chemins de code, vous allez bien.

Si vous n'appelez pas jetez , le gc sera finalement le jeter pour vous, mais cela peut conduire à la conflit de ressources.

Dans ce cas particulier, vous devriez probablement disposer l'original après la clonage, car on dirait que vous ne l'utilisez plus jamais.


0 commentaires

1
votes

Oui, cela pourrait être une fuite.

Si vous effectuez une copie d'un objet jetable (dans votre cas bitmap), vous devez immédiatement disposer de l'instance que vous n'avez plus besoin.

Utiliser le mot-clé n'est qu'une chose commodité autour manuellement ayant essayé finalement et appeler jetez (). Si dans votre situation, vous ne pouvez pas utiliser «Utilisation», utilisez simplement des blocs Essayez enfin et assurez-vous que la ressource dangereuse est nettoyée.


0 commentaires

2
votes

Je ne peux pas dire avec certitude, mais si vous avez peur que cela puisse, pourquoi ne pas cloner l'image à une nouvelle variable, jetez l'original, puis réaffectation:

public bool ImageCrop(int X, int Y, int W, int H)
{     
    Bitmap croppedImage = imageObject.Clone(new Rectangle(X, Y, W, H), imageObject.PixelFormat);
    imageObject.Dispose();
    imageObject = new Bitmap(croppedImage);
    croppedImage.Dispose();
}


0 commentaires

1
votes

La mémoire ne fuit pas dans le code géré, mais vous pouvez causer une fuite de ressources. Le bitmap est une enveloppe autour d'un objet de niveau inférieur sous Windows, et il est jetable de sorte que l'objet de niveau inférieur soit nettoyé correctement. Si vous laissez des objets non exposés, ils doivent normalement être disposés par le collecteur des ordures après un certain temps, mais il n'ya aucune garantie qu'il sera disposé.

Clonage d'une image crée un nouvel objet qui devrait être disposé en soi. Vous devez disposer de l'image d'origine lorsqu'il est remplacé par le clone. Vous pouvez utiliser le mot-clé à l'aide de pour celui-ci: xxx


2 commentaires

Pensez-vous que vous créez un nouvel objet "original", puis le disposer plus tard. Cela n'a rien à voir avec l'objet original et l'objet cloné?


@ Scientifique: oui, ça fait. L'objet d'origine est disposé et le clone est stocké dans la propriété.



1
votes

En supposant que le clone () fonctionne correctement, il vous donnera 2 objets jetables pour gérer. Les deux doivent être disposés ().

Donc je ne pense pas que cela résoudra votre problème.

Il n'est pas rare que la méthode renvoie un objet Idisposable, vous devez simplement assurer la gestion des ressources (sécurisée d'exception) à un niveau supérieur. Faites si soigneusement.


0 commentaires

1
votes

La clé pour éviter les fuites de ressources ou les bugs d'élimination prématurée consiste à garantir que chaque objet iDisposable sera tout à fait exactement un propriétaire clairement défini qui est responsable de la disposition. Parfois, un objet exposera une méthode par laquelle elle assumera la propriété d'un objet transmis. Si le propriétaire d'un objet le transmet à une telle méthode, le propriétaire d'origine de l'objet devrait pas le disposer. Sinon, le propriétaire d'un objet doit disposer d'un objet avant de détruire sa dernière référence à elle.

Si SOMECLASS possède imageObject , alors il devrait probablement disposer de cet objet avant de les détruire une référence. D'autre part, si un objet détient la seule référence à un autre objet, clonant l'objet détenu dans le but de réaffecter la référence d'origine semble être un peu d'odeur de code. Je ne sais pas comment ImageObject est attribué initialement, mais il semblerait qu'il soit soit créé dans votre objet, soit cloné sur la base d'un objet d'image transmis. Dans les deux cas, vous devriez être capable d'exercer suffisamment de contrôle sur le type de l'image passée pour choisir un type pouvant être recadré sans avoir à être (RE) cloné.


0 commentaires