Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Soft (not: weak) references in C++ - Is it possible? Is there an implementation?

In C++ I'm using boost::shared_ptr and boost::weak_ptr to automatically delete objects that are no longer needed. I know these work with reference counting.

In Java, memory is managed by a garbage collector, which consideres the built-in object references as strong, WeakReference as weak and SoftReference as something in between (may be collected by the GC, but may as well survive the GC), which is really handy for caching objects for some time, but throwing them away as soon as free memory is getting low.

So now I'm back in C++ and I miss the comfort of having soft references. I wonder if soft referencing is practicable with reference counting at all. When the last strong reference to an object is cleared, and there remains a soft reference, when would it be deleted after all? I could think of some schemes, but none of them seem clever to me.

Just in case there are proper semantics for soft references along with reference counting, I wonder if this has already been implemented, maybe in a way that's even compatible with boost::shared_ptr (or the C++ TR1 equivalent std::shared_ptr for that matter).

If the answer to both questions is no, what are the alternatives in an object caching scenario?

EDIT: Of course I'm talking of a situation when caching is actually useful, because the objects are costly to construct (think of several access to a database and queries of a network), yet there are too many to keep them all forever.

like image 496
Lena Schimmel Avatar asked Jul 04 '10 14:07

Lena Schimmel


People also ask

How are weak references implemented?

When a weak reference A is created to an object B, there would be an entry in the hashtable modified or created, whose key would be the pointer to B. "Dirty" - to store a special hash-value with each object, which would be zeroed when the object is destroyed.

What is a weak reference and how could it be useful?

As stated by Java documentation, weak references are most often used to implement canonicalizing mappings. A mapping is called canonicalized if it holds only one instance of a particular value. Rather than creating a new object, it looks up the existing one in the mapping and uses it.

What is the purpose of a weak reference in C?

A weak reference allows the garbage collector to collect an object while still allowing an application to access the object. If you need the object, you can still obtain a strong reference to it and prevent it from being collected.

What are weak references difference between weak and strong references?

A weak reference is just a pointer to an object that doesn't protect the object from being deallocated by ARC. While strong references increase the retain count of an object by 1, weak references do not. In addition, weak references zero out the pointer to your object when it successfully deallocates.

Which reference will be finalized but memory will not be reclaimed and useful in the scenario where notification is required before object is collected?

A soft reference will only get removed if memory is low. A weak reference will get removed on the next garbage collection cycle. A phantom reference will be finalized but the memory will not be reclaimed. Can be useful when you want to be notified that an object is about to be collected.

What is weak reference garbage collection in case of such references?

//eligible for garbage collection. Weak References: Weak Reference Objects are not the default type/class of Reference Object and they should be explicitly specified while using them. This type of reference is used in WeakHashMap to reference the entry objects .


1 Answers

As others pointed out, you can find referenced counted pointers (and their attendant weak counterparts) in the Boost library, but what's missing from the soft reference idea is some awareness of the runtime environment's memory constraints. In Java, for example, a SoftReference isn't materially different from a WeakReference in its capabilities; rather, it's the contract for how the runtime will preserve or evict the two kinds of references in the face of memory pressure that differs.

In order to mimic this behavior in C++, you'd have to build a memory-aware reference cache that held strong references on objects that the rest of your application would hold weakly. When the cache determined that the application was scratching its memory usage ceiling — or any other constraining criteria — it would release the strong references, surrendering the objects for "collection" (reaching the zero reference count) and allowing the weak references in use to later detect invalidation.

like image 109
seh Avatar answered Sep 22 '22 10:09

seh