A way for dynamically allocated objects to be automatically deleted after a set period of time
I'm looking for suggestions for ways of having all objects of a particular class I'm de开发者_运维百科aling with (lets call it class A) to automatically "self-destruct" after a fixed period of time. For the sake of argument let's say after exactly 3 days.
- It is guaranteed that all objects of class A will only ever be created on the heap.
- It is also guaranteed that no object of class A will ever be accessed 72 hours after it was created (so deleting the object after 3 days is entirely safe).
[These objects will be accessed by client code potentially multiple times for up to 72 hours. While the client code can indeed invoke a destroy() method on each object of class A when it knows its done using it, I don't want to rely on the client cleaning up these objects. To avoid possible memory leaks, I want to ensure they are cleaned up without client intervention, i.e. for them to self-destruct after 72 hours.]
What are the recommended ways of doing this, to create-and-forget?
You should really use RAII for resource managment in C++. In your case, using a boost::shared_ptr
could solve your problem.
One approach is to have a "registry" for all those objects and something that would periodically check that "registry" and delete too old objects. That could be a timer procedure or a separate thread or some routine periodically run from the client code. When you add an object address to the registry you store the time of adding along with the address. Of course those objects will need some common base to allow polymorphic destruction and deallocation.
You might want to implement that they expire if they are not used for a period of time. This is common with client/server technology where you cache items that a client is using so they are readily available when they are requested, and it is a technique for connectionless servers where clients have a session that request objects and use them, so no it is not a crazy question, it has practical benefits.
I generally find that I would use LRU technique, (least recently used) and the best container for this is std::list. When an item is accessed you can "splice" your list to move the item to the front. Much of the time you deal with list-iterators, which remain valid even when moved around the list.
At various times you may do some "cleanup" on your list. You could have a process that checks over a period of time for expired items, or it might be event driven and know when the next expiry time is.
Of course if the client comes back and attempts to access the item you must be ready to recreate it in the state it was at the point of deletion.
Maybe you can instantiate a static std::list<Your_class *>
in your class. Every new instance of the class is pushed to the back of that list, and a timer calls regularly a function that pops and destroys items in the front of the list when they are too old.
Note that if you want to extend the lifespan of a particular instance in the middle of its life, then a list structure is probably not good because you will have to perform a linear scan…
In this case, you want a container in which you have quick insert and removes at both ends, and where you can find an element quickly, with quick deletions in the middle of it. I can only suggest also having a static std::map<Your_class *, std::list<Your_class *>::iterator>
that allows you to quickly find elements in your list.
Otherwise read the answer about shared_ptr
s. This is the best advice that can be provided to you. If nothing prevents you from using it, then switch to it and do not implement what I told you.
i think if you had something like become and had the object become a none singleton that would reject the method calls on it the process of becoming none would be managed by a resource pool that would keep a reference to each object and the time it was created and when the object becomes older than 3 days it would have it become none
I would implement some simple garbage-collector system and allocate your objects through it.
Assuming that the objects cannot cross-reference themselves, it should be fairly easy.
For example, the garbage-collector class could hold a double-ended queue (e.g. std::deque
) containg object pointers and their creation time. When creating new objects, they would be put at the end of the queue. From time to time I would call a function purge()
would be called which would check objects which are at the front of the queue (the oldest) and remove them when applicable.
精彩评论