【问题标题】:Is the default lodash memoize function a danger for memory leaks?默认的 lodash memoize 函数是否存在内存泄漏的危险?
【发布时间】:2016-07-26 21:24:35
【问题描述】:

我想使用memoize,但我担心缓存会无限增长,直到出现悲伤的时刻。

我无法通过 google/stackoverflow 搜索找到任何内容。

附:我正在使用 lodash v4。

【问题讨论】:

  • 它不会:它完全按照预期工作。如果您想“刷新”缓存 - 只需重新创建一个包装函数。这几乎不是泄漏,因为您故意和自愿存储所有数据。
  • 你也可以使用 Wea​​kMap 作为你的缓存,如果它对你可用,并且你是按对象键控的。

标签: javascript lodash


【解决方案1】:

除非您指定不同的缓存类型,否则 Lodash 会保留所有记忆数据。


默认缓存是lodash的MapCache:
https://github.com/lodash/lodash/blob/4.14.0/lodash.js#L1968

memoized 值存储在不同的数据结构中,取决于 key 是否适合散列(以及 ES6 Map 在环境中是否可用):
https://github.com/lodash/lodash/blob/4.14.0/lodash.js#L1987 https://github.com/lodash/lodash/blob/4.14.0/lodash.js#L5561

如果您查看所有这些数据结构的“设置”方法,您会注意到没有提供任何类似 LRU 等的方法:
哈希#set:https://github.com/lodash/lodash/blob/4.14.0/lodash.js#L1832
ListCache#set: https://github.com/lodash/lodash/blob/4.14.0/lodash.js#L1940
地图#set:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/set

【讨论】:

  • LRU 会打破记忆化的整个概念并打破它的契约。
  • 我过去曾使用带有 LRU(“max”选项)的 memoizee 作为缓存昂贵渲染输出的便捷方式。在那个特定的应用程序中,我得到了一批与我的函数匹配的输入,但随着时间的推移,输入会发生变化。缓存未命中不如不占用内存重要。
  • 我已经接受了这个,虽然我可能错过了内存泄漏术语,但这个答案确实是我正在寻找的核心。
【解决方案2】:

简短的回答是否定的。

当您使用memoize 函数时,您接受以下合同:

  1. 该函数只会使用给定的参数调用一次
  2. 只要有必要保证 #1(永远),缓存就会一直存在

所以只有永久保存数据的实现才能符合要求。

经常混淆的是“内存泄漏”,只是“低效”使用内存。

在这种情况下 - 如果这对您来说是个问题,那么您有责任在它对您的算法有益时重新创建一个记忆函数。因为只有你知道什么时候这样做是安全的,而且它不能自动完成。

【讨论】:

  • 答案也很好,我想我只是误用了内存泄漏这个词。我担心的实际上是内存的过度消耗。猜猜这里需要注意的含义略有不同。谢谢
  • 所以最后我使用了一个名为 reselect 的库,它可以响应我的应用程序状态的变化(我正在使用 react/redux),然后输出一个记忆函数。我认为这符合您的建议。我还必须提供自己的 memoize 解析器,因为我对函数使用了多个参数。单元测试正在工作。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-12-16
  • 1970-01-01
  • 2011-01-29
  • 2011-05-08
  • 2012-12-11
  • 2011-06-26
  • 2011-10-07
相关资源
最近更新 更多