我有一个大约16000个节点的大型数据集。对于每个节点,我基于某种相似性度量找到k个最近邻居。前k个邻居驻留在优先级队列中(自己实现)。随着模拟的进行(计算所有邻居的knn),内存使用量不断增加,模拟变得更慢。如果我想要删除先前用户的优先级队列,我将继续释放内存,我该怎么办呢?这是唯一可能的原因还是因为性能缓慢还有其他原因?
答案 0 :(得分:4)
Ruby的垃圾收集应该处理这个问题,只要你不保留对你想要释放的对象的引用。确保没有参考文献。
您可能还想查看GC模块:http://www.ruby-doc.org/core-2.1.0/GC.html
答案 1 :(得分:2)
如果你允许你的队列增长,那么你通常应该设计一些缩小它的方法。
您将结构称为“队列”。所以我假设一些元素流入(即添加到数组中),并且一些元素流出。当他们流出时你怎么处理他们?你是否从队列中删除它们?当你从队列中删除变量或它们的特定阵列时,你是nil
吗?在许多旧元素被填满之后,你是否缩小了数组?
如果你是,那就应该没问题。
Ruby有一个GC,因此每个“丢失”的对象都应该在某个时间点自动删除。注意'应该'和'在某些时候'。很难说或何时保证。如果你有很多可用内存,那么GC可能还没有运行。尝试手动踢它,看看内存使用量是否下降。
如果您没有删除旧条目,那么它永远不会是正常的。在您使队列实际忘记对象之前,对象将保持活动状态并占用内存。见上文。
如果你只是nil
- 他们并且你从不收缩或重复使用数组中的旧空间,那么GC将扫描分离的旧对象,但是你的数组仍会随着时间的推移而增长。拥有1000000个元素的数组是不明智的,其中999900是nil
。 Splice
数组,或将其复制到较小的数组或其他内容。并调整您的算法,因为生活元素的索引会发生变化。
当然还有一个案例 - 你正在做所有事情,GC工作,丢失的对象被删除。并且可能是队列只是增长到极大的尺寸,因为元素不够快dequeued
(处理和删除)。例如,您每秒添加1000个新元素,并且工作线程删除10个元素/秒。一小时后,即使一切正常,您也会有一个很好的(并且不断增长的)积压。好。你明白了。这是不容易解决的,您必须仔细检查并纠正整个设计。
例如,对于快速补丁,您可以:
但这些只是提示。在这种情况下,你必须自己重新考虑它,因为只有你知道关于确定你能做什么以及你不能忘记什么的确切要求的重要部分。