C # "generic pointer" for alternative memory management?

I am looking for a way to do this in C #:

  • an Asker object will request a Giver object for Resource objects.
  • when asked, Giver will look for it in the dictionary for the existing resource match. If it is found, it will return a resource link; otherwise, it will create a new resource from the database data, save this link in the dictionary, and finally return the link.
  • Asker can request the same resource more than once, in which case Giver will return the same resource from the Dictionary as many times.
  • Asker may not use this resource at any time, in which case it does nothing for the resource.

  • Problem: how can the Sensor detect any resource that it no longer uses and remove it from the Dictionary? It is advisable that Giver should do this without the help of Asker.

Is it possible? I can not solve this problem.

EDIT: Thanks to everyone for the great answers. Especially WeakReferences. I did not know that they were there. But I have two main goals that I could clarify.

  • The donor should not rely on Asker to receive notice.
  • While this resource is being used, all links must point to the same resource so that changes in the resource are reflected in all places where the same resource is used.

EDIT: [Invalid code block removed]

+3
source share
8 answers

To get started, what you're talking about is the basic idea of ​​the IDisposable interface: a deterministic way of allocating resources. Although its main use is to interact with unmanaged resources that require explicit release (or interact with objects that do this), its use is not limited to this.

Unfortunately, this does not meet your last requirement: since it is deterministic, it must be called by someone. That someone was supposed to be Asker.

The only solution I can come up with is to use the WeakReference class in your Giver object. This allows you to maintain a link to an instance that does not prevent it from collecting garbage (after collecting it, your link becomes null ).

Unfortunately, this is not deterministic. Your link will become null (and IsAlive will be false ) after the actual collection of the object, which is not guaranteed at any particular time (or even during the entire life of your application).

Given these caveats, you can do something like this:

 public class Giver { private Dictionary<string, WeakReference> cache = new Dictionary<string, WeakReference>(); public object GetResource(string resourceName) { WeakReference output; object returnValue = null; if(cache.TryGetValue(resourceName, out output)) { if(output.IsAlive) returnValue = output.Target; if(returnValue == null) cache.Remove(resourceName); } if(returnValue == null) { returnValue = ...; // get the actual resource cache.Add(resourceName, new WeakReference(returnValue)); } return returnValue; } } 
+1
source

All this functionality is encapsulated in System.Web.Caching.Cache .

It can be used safely outside of ASP.NET and has a mechanism for expiration, reboot ...

+2
source

You can save the WeakReference resource in the dictionary instead of the resource itself. This will not interfere with garbage collection.

When you select a value (weak link) from the dictionary, you will need to get the Target and see if it is null. If so, the resource has been garbage collected and you need to recreate it. Otherwise, you can return the target as a cached resource.

I do not believe that there is much control over how "important" WeakReference is considered - I do not think you can say that it should do this before gen2, for example. Of course, you may have some other data structure to make sure that any resource has been cached for at least (say) 5 minutes, since it referred to it for a long time.

If you approach this approach, you can also periodically review the dictionary and retrieve entries for which the target has already been garbage collected so that your dictionary does not fill out useless entries. If the set of keys is fixed and not too large, this may not be worth it, especially considering the timing that you are likely to need.

+2
source

Asker should tell Giver that he is no longer using the resource.

At this point, Giver should delete the resource.

Observer pattern can help here.

0
source

You probably need a dictionary [string, WeakReference]. MSDN has an example of how to use them to implement a more or less requested system:

http://msdn.microsoft.com/en-us/library/system.weakreference.aspx

Just scroll down to the "Examples" section, which shows how to implement the resource cache.

WeakReference does not block objects, they just go null when the object they point to is fixed by the garbage collector.

0
source

You can use the WeakReference class in Giver .

0
source

One way to do this is with weak links. Here is an article I wrote about this approach several years ago:

http://www.devx.com/dotnet/Article/36286

0
source

In addition to the Oded comments, here is a link to the IObserver interface to get you started:

http://msdn.microsoft.com/en-us/library/dd783449.aspx

0
source

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


All Articles