C++ 中的软(不是:弱)引用- 是否可以?有实施吗?

发布于 2024-09-07 19:16:15 字数 861 浏览 1 评论 0原文

在 C++ 中,我使用 boost::shared_ptrboost::weak_ptr 自动删除不再需要的对象。我知道这些与引用计数一起工作。

在 Java 中,内存由垃圾收集器管理,垃圾收集器将内置对象引用视为WeakReference视为SoftReference 作为介于两者之间的东西(可能被 GC 收集,但也可能在 GC 后幸存下来),这对于缓存对象一段时间但将其丢弃确实很方便一旦可用内存变少。

所以现在我又回到了 C++,我怀念软引用带来的舒适感。我想知道软引用对于引用计数是否可行。当对对象的最后一个引用被清除,并且仍然存在一个引用时,它到底什么时候会被删除?我可以想到一些方案,但对我来说,这些方案都不聪明。

以防万一软引用和引用计数有正确的语义,我想知道这是否已经实现,也许以一种甚至与 boost::shared_ptr 兼容的方式(或 C++ TR1 等效< code>std::shared_ptr 就此而言)。

如果两个问题的答案都是“否”,那么对象缓存场景中有哪些替代方案?

编辑: 当然,我谈论的是缓存实际上很有用的情况,因为对象的构建成本很高(想想对数据库的多次访问和网络查询),但有太多的对象无法构建。永远保留它们。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

惜醉颜 2024-09-14 19:16:15

正如其他人指出的那样,您可以找到引用的计数指针 (及其伴随的对应项)在 Boost 库中,但是软引用想法中缺少的是对运行时环境内存约束的一些认识。例如,在 Java 中,SoftReference 在功能上与 WeakReference 没有本质上的区别;相反,它是关于运行时如何执行的契约面对不同的内存压力,保留或驱逐两种引用

为了在 C++ 中模仿这种行为,您必须构建一个内存感知引用缓存,该缓存对应用程序的其余部分将持有的对象强引用进行保存 。当缓存确定应用程序正在触及其内存使用上限(或任何其他约束标准)时,它将释放强引用,放弃对象以进行“收集”(达到零引用计数)并允许稍后使用弱引用检测失效。

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.

扮仙女 2024-09-14 19:16:15

如果您确实想复制此行为,您可以使用垃圾收集器(如下所示:http ://www.hpl.hp.com/personal/Hans_Boehm/gc/)并使用它来处理您的对象或其子集,其中使用 SoftReferences 会很有用。

但我更愿意寻求一种更原生于 C++ 的解决方案,而不是复制 Java 行为 - 但没有什么可以阻止你这样做。

If you really want to replicate this behavior you may use a garbage collector (like this: http://www.hpl.hp.com/personal/Hans_Boehm/gc/) and use it to take care of your object or a subset of them, where using SoftReferences would be useful.

But I'd prefer to go for a solution more native to C++ than replicating Java bahavior - but nothing stops you of doing that.

冷月断魂刀 2024-09-14 19:16:15

您可以实现自己的 LRU 缓存,以及与此类缓存关联的新 smart_pointer。我不认为 Boost 或标准 C++ 中存在这样的结构(无论如何,这是我的想法)。如果您正在开发 Web 应用程序或其他东西...您可以使用 libmemcached,它是 memcached 的 C 接口。

我发现很难想象这样一种情况:这样一个对象的构造/销毁成本如此之高……而重新初始化的成本却很低……LRU 缓存会变得有用。但如果您确实需要一个,您就有实际构建它的工具。

You can implement your own LRU cache, and a new smart_pointer associated with such a cache. I don't think such a structure exists in Boost or standard C++ (off the top of my head anyway). If you are doing a web application or something... you can use libmemcached, which is the C Interface to memcached.

I find it hard to think of a situation where such an object would be so costly to construct / destroy... while it would be cheap to reinitialize... that a LRU cache would become useful. But if you really need one, you have the tools to actually build it.

白况 2024-09-14 19:16:15

您可以使用 buffcacher 之类的工具将应用程序外部的软引用数据移至操作系统中。

据我所知没有图书馆提供这个,我只自己推出过。

它是如此快速和公平,以至于它对于在网络服务器中缓存“安全cookie”的验证以及其他对于传统缓存来说几乎很小的任务非常有用。

You can move your soft-referenced data outside your application into the OS using something like buffcacher.

I know of no library offering this, I've only ever rolled my own.

Its so fast and fair that it gets useful to cache the validation of 'secure cookies' in webservers and other tasks that seem almost small for a conventional cache.

小帐篷 2024-09-14 19:16:15

不,C++ 中没有这样的东西。也不应该有。每个物体都有重要的用途。如果没有,为什么你还留着它?以这种方式保留对象会导致内存泄漏。如果你需要一个对象,你就需要它。如果不这样做,就毁掉它。有用和无用之间没有中间地带,要么有用,要么没有。

如果你绝望的话,编写自己的垃圾收集器并自己实现这样的东西也不是不可能的。但我建议不要需要它们或根本不使用它们。

编辑:在对象缓存中,人们通常使用 LRU 缓存。当缓存未命中时,对最近最少使用的对象的引用将被销毁(如果缓存已满),创建新对象并将其作为最近使用的对象放入,而所有其他对象都会向下移动。但是,在实际需要 C++ 中的缓存策略之前,您通常需要从磁盘检索项目。创建大多数对象的成本并没有那么高。

No, there is no such thing in C++. Nor should there be. Every object serves an important purpose. If it didn't, why do you still have it? Keeping objects around in this way is a memory leak. If you need an object, you need it. If you don't, destroy it. There is no in-between between useful and useless, either it serves a purpose or it doesn't.

If you're desperate, it is not impossible to write your own garbage collector and implement such a thing yourself. But I'd recommend against needing them or using them at all.

Edit: In object caching, people normally use LRU caches. When you have a cache miss, the reference to the least recently used object is destroyed (if the cache is full), the new object is created and put in as the most recently used, and all the others are moved down. However, you typically need to be retrieving items from disk before you actually need a caching strategy in C++. The cost of creating most objects is simply not that great.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文