c# object caching and reference counting

C

colin

Hi,
I need to cache various resource objects such as images for example,
wich might be referenced from multiple objects
(wich could be considered documents for ease of discusion)
and the idea is simply to make sure they arnt duplicated
as they take up considerable memory, so I can look up
to see if an existing copy exists.

however once they are in the cache how can I ensure they get released,
when they are no longer referenced, as now my cache list is referencing
them,
so the GC wont free them.

can I look at the underlying reference count and so release it from my cache
if the count is 1?
I cant seem to find how to do this, at least not inside c#.

I realy dont want to have to keep a track of seperate reference count as
this
is something I hoped id got away from with managed code.

or is there a way to find all existing objects of a certain class?

a couple of alternatives would be

1) to hold a wrapper wich releases the bitmap when it hasnt been used for
ages,
but can reload it when required from the source,
however this needs a reference to the source wich means that the source no
longer gets released
when its dereferenced.

2) to have a root item wich all source documents are referenced from and to
periodically
keep the cache up to date with this. this is probably much like the GC
operation.
however this is probably quite complicated and not all the source types are
under my control.

I thought I heard someone talk about such a cache, however when I tried to
look
there are so many other types of cache, relating to .net assemblies etc.

the images are actually textures for my 3d objects,
but theres other types too wich are large enought o try and avoid
duplicating.

many thanks
Colin =^.^=
 
M

Marc Gravell

Perhaps you could try using a WeakReference in the list; you will need
to cast it to image to extract it, but a WeakReference won't prevent GC
- if everything else has let go of the image, then it will be collected,
and the WeakReference will report this when you look at it.

Marc
 
T

Terry Rogers

Hi,
I need to cache various resource objects such as images for example,
wich might be referenced from multiple objects
(wich could be considered documents for ease of discusion)
and the idea is simply to make sure they arnt duplicated
as they take up considerable memory, so I can look up
to see if an existing copy exists.

however once they are in the cache how can I ensure they get released,
when they are no longer referenced, as now my cache list is referencing
them,
so the GC wont free them.

can I look at the underlying reference count and so release it from my cache
if the count is 1?
I cant seem to find how to do this, at least not inside c#.

I realy dont want to have to keep a track of seperate reference count as
this
is something I hoped id got away from with managed code.

or is there a way to find all existing objects of a certain class?

a couple of alternatives would be

1) to hold a wrapper wich releases the bitmap when it hasnt been used for
ages,
but can reload it when required from the source,
however this needs a reference to the source wich means that the source no
longer gets released
when its dereferenced.

2) to have a root item wich all source documents are referenced from and to
periodically
keep the cache up to date with this. this is probably much like the GC
operation.
however this is probably quite complicated and not all the source types are
under my control.

I thought I heard someone talk about such a cache, however when I tried to
look
there are so many other types of cache, relating to .net assemblies etc.

the images are actually textures for my 3d objects,
but theres other types too wich are large enought o try and avoid
duplicating.

many thanks
Colin =^.^=

You could use a WeakReference to store items in the cache, that way
the images can still be garbage collected as normal.

For example:

public class ImageCache
{
private IDictionary<string,WeakReference> _cache = new
Dictionary<string, WeakReference>();
public Image GetImage(string path)
{
WeakReference reference;
if(_cache.TryGetValue(path, out reference))
{
if(reference.IsAlive)
{
return (Image) reference.Target;
}
else
{
// image has been garbage collected
// remove reference from cache
_cache.Remove(path);
}
}

// not in cache, so load
Image image = Image.FromFile(path);
reference = new WeakReference(image);
_cache.Add(path, reference);
return image;
}
}
 
P

parez

colin said:
Hi,
I need to cache various resource objects such as images for example,
wich might be referenced from multiple objects
(wich could be considered documents for ease of discusion)
and the idea is simply to make sure they arnt duplicated
as they take up considerable memory, so I can look up
to see if an existing copy exists.

however once they are in the cache how can I ensure they get released,
when they are no longer referenced, as now my cache list is referencing
them,
so the GC wont free them.

can I look at the underlying reference count and so release it from my cache
if the count is 1?
I cant seem to find how to do this, at least not inside c#.

I realy dont want to have to keep a track of seperate reference count as
this
is something I hoped id got away from with managed code.

or is there a way to find all existing objects of a certain class?

a couple of alternatives would be

1) to hold a wrapper wich releases the bitmap when it hasnt been used for
ages,
but can reload it when required from the source,
however this needs a reference to the source wich means that the source no
longer gets released
when its dereferenced.

2) to have a root item wich all source documents are referenced from and to
periodically
keep the cache up to date with this. this is probably much like the GC
operation.
however this is probably quite complicated and not all the source types are
under my control.

I thought I heard someone talk about such a cache, however when I tried to
look
there are so many other types of cache, relating to .net assemblies etc.

the images are actually textures for my 3d objects,
but theres other types too wich are large enought o try and avoid
duplicating.

many thanks
Colin =^.^=

I wish i had known about this WeakReference class two years ago. I had
implemented a similar class for expirable objects that checked the
"time inserted" before returning the object or null.
Also used a timer to remove the objects from the hashtable based on
inserted time.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top