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

49 天前
 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']) 这段代码去掉 就没问题了

7644 次点击
所在节点    React
75 条回复
qping
49 天前
这段代码看着是想实现
1. 订阅 websocket 的地址,然后更新到 data.value
2. 如果 data.value 发生改变,重新排序( remindEndTime > now 的数据显示到最前面),更新到 visibleData.value

如果上面需求理解正确的话,那实现就很奇怪
1. 为什么 list 定义不在 handleData 内,既然用完置为 null ,那就不应该是个全局变量
2. 为什么使用 setInterval 来更新数据,不使用 watch 来监听 data.value
jy02534655
49 天前
list = data.value; 改成 const list = data.value;

visibleData.value = list 改成深拷贝复制一份看看

你这个每 0.3 秒就执行一次会不会太快了,setInterval 的话会不管 handleData 是否执行完成都会执行吧?
要不在 handleData 里面写 settimeout ,等 handleData 执行完,并且通过 nextTick 自调用来实现循环看看呢
lp4298707
49 天前
@NessajCN list 在函数外部定义的,我改成在 handleData 内部定义也是一样的结果
lp4298707
49 天前
@qping 因为想要实现 remindEndTime > now 就显示最前面 因为需要实时刷新 now 我就设置的 1S 执行一次 handleData, 这里我因为想要快速看到效果 把时间设置得更短了
lp4298707
49 天前
@jy02534655 你说的深拷贝 递归调用 我都试过了 都是一样的效果
qping
49 天前
@qping 第二个看明白了,是想不停的根据当前时间去重新计算排序

你可以试试把 list 改成 handleData 内定义试试
NessajCN
49 天前
@lp4298707
list = orderBy(list, ['sort', 'updateTime'], ['asc', 'desc']);
改成
orderBy(list, ['sort', 'updateTime'], ['asc', 'desc']);

或者
const ordered_list = orderBy(list, ['sort', 'updateTime'], ['asc', 'desc'])
visibleData.value = ordered_list
CivAx
49 天前
@yxd19 #6 好酷!原来还可以这样 Highlight 页内文本!
yxd19
49 天前
@CivAx chrome 某次更新之后的功能吧。选中文字右键菜单。
nevermoreluo
49 天前
打印过时间吗?
有没有可能数据太多了。。。。setInterval 300 毫秒来不及处理?
imherer
49 天前
@CivAx 这个 Highlight 是咋实现的哦
Arrowing
49 天前
全是闭包,不出问题才怪呢。
最主要的 orderBy 定义没写出来
g0python32
49 天前
lp4298707
49 天前
@Arrowing orderBy 就是 loadsh 的 orderBy
lp4298707
49 天前
@nevermoreluo 我改成 2 秒也是一样的 只是内存增长速度变缓了
lisongeee
49 天前
看起来你的 data 是 vue 里的的 ref ,如果是 vue 的话

你换成 shallowRef 试试呢,ref 有深度劫持的问题,shallowRef 不会有这个问题
asdjgfr
49 天前
你这代码复制下来运行了一下也没有内存泄漏呀
retanoj
49 天前
@qping #21 我想问个小白问题
subscribe 订阅了指定 topic 之后,每次 topic 有新消息来不就会触发 res => {} 函数吗?
为啥还要用 setInterval 做个 timer
gitdoit
49 天前
看了下 orderBy 的源码, 会创建新的数组;但是搞不懂为什么内存会持续增长. 大对象会被立即回收吗?
chairuosen
49 天前
zhua 一下内存快照,看看谁增长的快

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

https://www.v2ex.com/t/1036400

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

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

© 2021 V2EX