How can I get rid of an object (say Bitmap) when it becomes an orphan?

I have class A providing bitmaps to other classes B, C, etc.

Class A now holds its bitmaps in a ring queue, so after a while it will lose the link to the bitmap.

While it is still in the queue, one bitmap can be checked by several classes, so, say, B and C can contain a link to the same bitmap. But it can also happen that only one of them checks the bitmap or even none of them.

I would like to get rid of the bitmap when it is no longer needed by either A, B, or C.

I believe that I should make B and C responsible for somehow signaling when they finished using it, but I'm not sure about the general logic.

If this is a call to call DisposeIfNowOrphan (), which will be called three times in this example:

1 - when the bitmap is unloaded from the queue in class A

2 - when B is finished with it

3 - when C finished with him

If this is the best strategy, how can I assess the condition of orphans?

Any advice would be appreciated.

+4
source share
4 answers

Let class A provide a wrapper class instead of a direct bitmap. The wrapper class must implement IDisposable itself and can be used to maintain the counter. Each consumer can get their own shell, which refers to one bitmap. Class A preserves the trap of all bitmaps and all wrappers. Use the WeakReference in class A to track the wrappers, so if the consumer is not called by dispose, he will receive GC'd and the provider may know that he is no longer referencing.

+3
source

Bitmap inherits from Image , which implements IDisposable , so when you finish using the instance, you should call it Dispose() . This will clear the unmanaged resource in Image .

However, Image also implements the finalizer, so if for some reason you cannot call Dispose() , the resource will be fixed during the finalization of the instance, which will happen at some point after the instance is no longer referenced.

+2
source

If memory usage is not such a big problem, and correctness and clarity are more important ...

Give each recipient their own copy of the bitmap and get a using () statement around the code used.

Now your control code is very simple, and your consumption code is also very simple. It is also very easy to see (prove?) That all this will work even when your consumers may have exceptions and other code paths that make it difficult (or impossible) to make sure that the link counts have been reduced (or such).

Using the time you saved by developing your own GC solution for common bitmaps, take the money and buy another RAM finger for your server.

+1
source

If, on the other hand, peak memory consumption is a key issue ... but you still want a β€œsafe” approach, when you can be sure that the bitmap's lifetime is managed properly regardless of the user code you can invert the problem and say that the manufacturer is fully responsible for all operations on images in its stream (or streams). Therefore, instead of transferring images to other classes that you are working on, you are asking other classes to transfer actions to be performed on images. You maintain a queue of pending actions and you can look in a queue in a queue to decide which images need to be thrown from the buffer, based on the fact that there will be no future work on them.

Since these images are likely to be on a large heap of an object, it is important to control their life spans to minimize fragmentation of the heap of large objects.

0
source

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


All Articles