Will a disposable object clown cause a memory leak in C #?

Check this code:

.. class someclass : IDisposable{ private Bitmap imageObject; public void ImageCrop(int X, int Y, int W, int H) { imageObject = imageObject.Clone(new Rectangle(X, Y, W, H), imageObject.PixelFormat); } public void Dispose() { imageObject.Dispose(); } } 

Bitmap is ICloneable , IDisposable in C #.

To avoid memory leaks, for a one-time object, usually use using , then the object will be automatically deleted by the system regardless of how your code went wrong.

In my example, I cannot use using , since I do not want to delete the object, I need it later (the whole class will be located with its IDisposable .

My question is: I have an imageObject , then I use its Clone() method to clone a new object and pass it to the old object variable. This will lead to the fact that the object (either cloned or original) will not go anywhere and will never be deleted, a memory leak.

[EDIT]

It seems that most Clone views call an extra object, the old one should be Dispose()

Here is the new code:

  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 } 

and that should be right Dispose the resources.

+6
source share
6 answers

The key to preventing resource leaks or errors associated with premature destruction is to ensure that every IDisposable is always exactly the same clearly defined owner who is responsible for its removal. Sometimes an object exposes a method by which it will own the transferred object. If the owner of the object transfers it to this method, the original owner of the object should not dispose of it. Otherwise, the owner of the object must destroy the object before destroying its last reference to it.

If someClass belongs to ImageObject , then it should probably remove this object before destroying the link to it. On the other hand, if an object contains a single link to another object, cloning a held object to reassign the original link seems a bit like code smell. I donโ€™t know how ImageObject is initially assigned, but it might seem that it should be created inside your object or cloned based on the transferred image object. In any case, you must have sufficient control over the type of image transferred to select the type that can be cropped without the need for cloning (re).

+1
source

using just calls Dispose on the finally block.
As long as you call Dispose somewhere in all the codes, you're fine.

If you do not call Dispose , the GC will eventually delete it for you, but this can lead to a resource conflict.

In this particular case, you should probably delete the original after cloning, as it looks like you will never use it again.

+2
source

I canโ€™t say for sure, but if you are afraid that it might be, why not clone the image into a new variable, delete the original, and then reassign:

 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(); } 
+2
source

Yes, it could be a leak.

If you make a copy of a one-time object (in your case, Bitmap), you should immediately get rid of the instance that you no longer need.

using a keyword is just a convenient thing that manually uses try-finally and calls Dispose (). If in your situation you cannot use "use", just use try-finally blocks and make sure that the dangling resource is cleared.

+1
source

Memory does not leak in managed code, but you can cause a resource leak. A bitmap is a wrapper around a lower-level object in Windows, and it is one-time so that the lower-level object is cleaned correctly. If you leave objects undisclosed, they will usually be disposed of by the garbage collector after some time, but there is no guarantee that it will actually be deleted.

Cloning an image creates a new object that must be deleted by itself. You must delete the original image when it is replaced by a clone. You can use the using keyword to do this:

 public bool ImageCrop(int X, int Y, int W, int H) { using (Bitmap original = imageObject) { imageObject = original.Clone(new Rectangle(X, Y, W, H), imageObject.PixelFormat); } } 
+1
source

Assuming that Clone () is doing its job properly, it will give you 2 disposable objects to manage. Both must be Disposed ().

Therefore, I do not think this will solve your problem.

Often a method returns an IDisposable object, you just need to assure (exception) resource management at a higher level. Do this carefully.

+1
source

Source: https://habr.com/ru/post/905473/


All Articles