为啥这段代码会造成内存泄露啊?

2024-04-28 15:05:11 +08:00
 lp4298707

function handleData() {
  list = data.value;
  const now = new Date().getTime()
  list.forEach(item => {
    const isTop = item.remindEndTime > now
    item.shine = isTop;
    item.sort = isTop ? 0 : 1;
  })
  // 闪烁的放最前 再以更新时间排序
  list = orderBy(list, ['sort', 'updateTime'], ['asc', 'desc'])
  visibleData.value = list
  list = null
}

onMounted(() => {
  flightClient.subscribe(WS_PREFIX + '/xxx/xxx', res => {
    data.value = res
    handleData()
  })

  timer = setInterval(() => {
    handleData()
  }, 300)
})

onBeforeUnmount(() => {
  clearInterval(timer)
})

每次调用我都把 list 置为空了 为什么还是会导致内存蹭蹭涨?

如果把 list = orderBy(list, ['sort', 'updateTime'], ['asc', 'desc']) 这段代码去掉 就没问题了

11558 次点击
所在节点    React
75 条回复
ColdBird
2024-04-29 09:54:17 +08:00
@ysc3839 所以有的自动格式化工具会把+new Date()转成 Date.now()
ColdBird
2024-04-29 09:57:06 +08:00
感觉大概率就是 list 没有内部声明的原因,handleData 内声明一下 const list = XXX ,或者干脆不在前面生成 list ,直接 const list = orderBy
TKI
2024-04-29 10:51:19 +08:00
@lp4298707 #56 我这边看着占用 300M 左右,你是在浏览器的任务管理看的吗?;另外打开控制台,性能面板里看着内存没有一直增长。
davin
2024-04-29 11:30:05 +08:00
变量作用域被污染。另外,可以使用 requestAnimationFrame 替代 setInterval 。
privatezcoding
2024-04-29 12:00:45 +08:00
没有人关心从 flightClient 获取到的数据大小吗?
privatezcoding
2024-04-29 12:10:53 +08:00
我猜测你这里是因为原始网络数据本身就是个比较大的 list 。然后你又用 setInterval 每隔 300ms 用 orderby 创建新的数组。

解决方案:
1. flightClient 获取数据的时候根据 remindEndTime 和 updateTime 排序
2. setInterval 里直接对 remindEndTime 进行判断原地对数据进行处理
chill777
2024-04-29 13:40:03 +08:00
0.3s 执行一次,是不是太频繁了
Marthemis
2024-04-29 18:11:44 +08:00
这里没有内存泄漏,setinterval + orderBy 会创建大量的对象,因为 orderBy 的返回是一个新的数组。在内存快速增长到一定的阈值时会强制触发垃圾回收,从而最终稳定在一个较大的内存使用率值。(你可以加一个按钮去中断这个定时器,看看过一段时间内存会不会降下来)
lp4298707
2024-04-30 16:28:52 +08:00
@DOLLOR 感谢,这样确实解决了问题, 应该是 vue 内部没有及时回收这个资源? 在用 ref 的时候 内存只增不减 用 shallowRef 之后 到了一定的时间就会自动减少内存占用. 再次感谢
lp4298707
2024-04-30 16:30:08 +08:00
@wellerman 这种方式我试过,没有能解决问题, 最后我根据楼下的大佬的方式 使用 shallowRef 解决了这个问题
lp4298707
2024-04-30 16:30:34 +08:00
@TKI 是的 我在浏览器的任务管理器看的,最后我根据楼下的大佬的方式 使用 shallowRef 解决了这个问题
lp4298707
2024-04-30 16:31:51 +08:00
@visper 最后我根据楼上的大佬的方式 使用 shallowRef 解决了这个问题
lp4298707
2024-04-30 16:32:06 +08:00
@coderHu 最后我根据楼上的大佬的方式 使用 shallowRef 解决了这个问题
lp4298707
2024-04-30 16:32:38 +08:00
@privatezcoding 数据其实不大的, 最后我根据楼上的大佬的方式 使用 shallowRef 解决了这个问题
lp4298707
2024-04-30 16:33:31 +08:00
@ColdBird 内部声明我也试过的 一样的结果, 最后我根据楼下的大佬的方式 使用 shallowRef 解决了这个问题

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://ex.noerr.eu.org/t/1036400

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX