C ++中的软(非弱)引用 - 是否可能?有实施吗?

时间:2010-07-04 14:45:08

标签: c++ memory-management boost shared-ptr soft-references

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

在Java中,内存由垃圾收集器管理,垃圾收集器将内置对象引用视为 strong WeakReference weak 和{{3介于两者之间(可能由GC收集,但也可以在GC中存活),这对于缓存对象有一段时间非常方便,但是一旦可用内存变低就把它们扔掉。

所以现在我又回到了C ++中,我错过了软引用的安慰。我想知道软引用是否适用于引用计数。当对象的最后一个引用被清除,并且仍然存在 soft 引用时,它什么时候会被删除?我可以想到一些方案,但对我来说似乎都不聪明。

为了防止软引用和引用计数有适当的语义,我想知道这是否已经实现,可能以与boost::shared_ptr(或C ++ TR1等效std::shared_ptr兼容的方式实现。对于那件事)。

如果两个问题的答案都是否定,那么对象缓存场景中的替代方案是什么?

修改 当然,我说的是缓存实际上很有用的情况,因为构造的对象代价(想想几次访问数据库和网络查询),但是有太多的让他们永远保持下去。

5 个答案:

答案 0 :(得分:7)

正如其他人指出的那样,你可以在Boost库中找到referenced counted pointers(和他们的助手weak counterparts),但软参考想法中缺少的是一些意识到运行时环境的内存约束。例如,在Java中,SoftReference在功能上与WeakReference没有实质性的区别;相反,面对记忆压力,它是the contract for how the runtime will preserve or evict the two kinds of references

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

答案 1 :(得分:2)

如果你真的想要复制这种行为,你可以使用垃圾收集器(如:http://www.hpl.hp.com/personal/Hans_Boehm/gc/)并使用它来处理你的对象或它们的子集,其中使用SoftReferences会很有用。 / p>

但我更倾向于寻找一种比C ++更复制的解决方案而不是复制Java行为 - 但没有什么能阻止你这样做。

答案 2 :(得分:1)

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

我发现很难想象这样一个对象构建/销毁成本太高的情况......而重新初始化则很便宜...... LRU缓存会变得有用。但如果你真的需要一个,你可以使用它来实际构建它。

答案 3 :(得分:0)

您可以使用buffcacher等内容将软件引用的数据移到应用程序之外。

我知道没有图书馆提供这个,我只是自己推出。

它如此快速和公平,以便在Web服务器和其他任务中缓存“安全cookie”的验证非常有用,而这些任务对于传统缓存来说似乎很小。

答案 4 :(得分:-2)

不,C ++中没有这样的东西。也不应该。每个对象都有重要作用。如果没有,为什么还有呢?以这种方式保持对象是内存泄漏。如果你需要一个物体,你需要它。如果你不这样做,就把它摧毁吧。有用和无用之间没有任何中间,无论是有目的还是无用。

如果你绝望了,自己编写垃圾收集器并实现这样的事情并非不可能。但我建议不要使用它们或者根本不使用它们。

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