app端数据高频刷新后生成快照发现Integer没有回收

app端数据高频刷新后生成快照发现Integer没有回收

开发环境 版本号 项目创建方式
Windows win10 HBuilderX

产品分类:uniapp/App

PC开发环境操作系统:Windows

PC开发环境操作系统版本号:win10

HBuilderX类型:正式

HBuilderX版本号:4.76

手机系统:Android

手机系统版本号:Android 10

手机机型:随便机型

页面类型:vue

vue版本:vue2

打包方式:云端

项目创建方式:HBuilderX

示例代码:

<template> <view class="znc_weightData"> <view class="znc_weightbody" > <view class="znc_weightbody_mark" :style="`background-color:${weightBgColor};`"></view> <view class="znc_weightTop"> <view class="znc_Weights"> </view> <view class="znc_currentWeight"> <view class="znc_currentWeight_body"> <text class="znc_currentWeight_value"> {{currentWeight}} </text> <text class="znc_currentWeight_unit"> {{$store.state.unit}} </text> </view> </view> <view class="znc_weightStatus"> <view class="znc_statusItem zero"> <image v-show="zeroStatus == 0" class="znc_statusItem_imag active" :src="require(`@/static/${cachedTheme?'dark':'light'}/module/zero_active.png`)" mode="aspectFit"></image> <image v-show="zeroStatus != 0" class="znc_statusItem_imag" :src="require(`@/static/${cachedTheme?'dark':'light'}/module/zero_none.png`)" mode="aspectFit"></image> <view v-show="zeroStatus == 0" class="znc_statusItem_shadow"><view class="znc_statusItem_shadow_box zero_shadow"></view></view> </view> <view class="znc_statusItem stable"> <image v-show="weightStatus == 0" class="znc_statusItem_imag active" :src="require(`@/static/${cachedTheme?'dark':'light'}/module/stable_active.png`)" mode="aspectFit"></image> <image v-show="weightStatus != 0" class="znc_statusItem_imag" :src="require(`@/static/${cachedTheme?'dark':'light'}/module/stable_none.png`)" mode="aspectFit"></image> <view v-show="weightStatus == 0" class="znc_statusItem_shadow"><view class="znc_statusItem_shadow_box stable_shadow"></view></view> </view> <view class="znc_statusItem overload"> <image v-show="cacheOverLoad != 0" class="znc_statusItem_imag active" :src="require(`@/static/${cachedTheme?'dark':'light'}/module/overload_active.png`)" mode="aspectFit"></image> <image v-show="cacheOverLoad == 0" class="znc_statusItem_imag" :src="require(`@/static/${cachedTheme?'dark':'light'}/module/overload_none.png`)" mode="aspectFit"></image> <view v-show="cacheOverLoad != 0" class="znc_statusItem_shadow"><view class="znc_statusItem_shadow_box overload_shadow"></view></view> </view> </view> </view> </view> </view> </template> <script> export default { props:{ lightStatus:{ type:String, default:'NONE' }, weightStatus:{ type:Number, default: 1 } }, name:"weightData", data() { return { weightBgColor:'rgba(255, 255, 255, 0)', zeroStatus:0, currentWeight:'0.00', getWeightAndZeroStatusTimeID:null }; }, created() { if(this.getWeightAndZeroStatusTimeID){ clearInterval(this.getWeightAndZeroStatusTimeID) this.getWeightAndZeroStatusTimeID = null } this.getWeightAndZeroStatusTimeID = setInterval(()=>{ this.getWeightAndZeroStatus() },50) }, destroyed() { if(this.getWeightAndZeroStatusTimeID){ clearInterval(this.getWeightAndZeroStatusTimeID) this.getWeightAndZeroStatusTimeID = null } }, onHide() { if(this.getWeightAndZeroStatusTimeID){ clearInterval(this.getWeightAndZeroStatusTimeID) this.getWeightAndZeroStatusTimeID = null } }, computed: { cachedUnit(){ return "Kg" }, cacheOverLoad(){ return 0; }, // 缓存theme,避免每次渲染都计算路径 cachedTheme() { return 'dark'; } }, watch:{ lightStatus:{ deep:true, handler(){ let color = "rgba(255, 255, 255, 0)" switch(this.lightStatus){ // 回到初始化 case "AllOff": color = "rgba(255, 255, 255, 0)" break; //黄灯亮 上称状态 case "YELLOW": color = "#FFC700" break; //闪黄灯 保存中 case "FLASHYELLOW": color = "#C678DD" break; //闪绿 保存成功 case "FLASHGREEN": color = "#00B26A" break; //红灯亮 保存失败 case "RED": color = "#DC3E3E" break; } this.weightBgColor = color } } }, methods:{ getWeightAndZeroStatus(){ let myCurrentWeight = Math.floor(Math.random() * 1000) + 1; this.currentWeight = myCurrentWeight; this.zeroStatus = Number(myCurrentWeight) <= 10 ? 0 : 1 } } } </script> <style lang="scss" scoped> .znc_weightData{ padding:0 16rpx; width: 100%; display: flex; align-items: center; box-sizing: border-box; color: var(--text-color); .znc_weightbody{ position: relative; display: flex; flex-direction: column; align-items: center; justify-content:center; padding:24rpx; width: 100%; background-color: rgba(255, 255, 255, 0.08); border-radius:24rpx; box-sizing: border-box; overflow: hidden; .znc_weightbody_mark{ position: absolute; z-index: 1; top: 0; left: 0; width: 90%; height: 100%; } .znc_weightTop{ position: relative; z-index: 2; height:224rpx; width: 100%; display: flex; align-items: center; .znc_Weights{ height: 100%; width: 45%; display: grid; grid-template-columns:repeat(3,1fr); grid-column-gap:32rpx; .znc_Weight{ padding:0 32rpx 0 48rpx; display: flex; flex-direction: column; align-items: center; justify-content: center; width: 100%; border-radius:40rpx; background-color: rgba(255, 255, 255, 0.08); box-sizing: border-box; .znc_Weight_value{ font-size:44rpx; margin-bottom:24rpx; } .znc_Weight_icon{ width: 48rpx; height: 48rpx; } } } .znc_currentWeight{ flex: 1; height: 100%; display: flex; align-items: center; justify-content: flex-end; .znc_currentWeight_body{ display: inline-block; vertical-align:bottom; .znc_currentWeight_value{ font-size:176rpx; font-weight: 700; margin-right:24rpx; } .znc_currentWeight_unit{ font-size:75rpx; font-weight: 700; } } } } .znc_weightStatus{ height: 100%; display: flex; flex-direction: column; align-items:center; justify-content: space-between; margin-left:88rpx; .znc_statusItem{ position: relative; width: 56rpx; height: 56rpx; .znc_statusItem_imag{ width: 100%; height: 100%; } .zero_shadow{ box-shadow: 0px 0px 40rpx 20rpx $znc_zero; } .stable_shadow{ box-shadow: 0px 0px 40rpx 20rpx $znc_stable; } .overload_shadow{ box-shadow: 0px 0px 40rpx 20rpx $znc_overload; } .znc_statusItem_shadow{ position: absolute; top: 0; left: 0; z-index: 1; width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; .znc_statusItem_shadow_box{ width: 1%; height: 1%; } } } } } } </style>

操作步骤:


将代码粘贴后使用

预期结果:

能够被Gc回收


实际结果:


没有被回收

1 回复

在uni-app中,高频定时器(50ms间隔)确实容易导致内存泄漏,特别是Integer对象未被GC回收的问题。主要原因是:

  1. 定时器未正确清理:虽然你在destroyedonHide生命周期中清理了定时器,但在组件快速创建销毁的场景下,可能存在清理不及时的情况。

  2. 频繁的对象创建:每50ms执行Math.floor(Math.random() * 1000) + 1会产生大量临时Number对象,在V8引擎中可能被优化为Integer对象。

  3. Vue响应式系统开销:频繁赋值this.currentWeightthis.zeroStatus会触发Vue的响应式更新,增加内存压力。

优化建议

// 在data中预先定义变量,避免重复创建
data() {
  return {
    weightBgColor: 'rgba(255, 255, 255, 0)',
    zeroStatus: 0,
    currentWeight: '0.00',
    getWeightAndZeroStatusTimeID: null,
    tempWeight: 0 // 添加临时变量
  };
},

methods: {
  getWeightAndZeroStatus() {
    // 使用临时变量减少对象创建
    this.tempWeight = Math.floor(Math.random() * 1000) + 1;
    
    // 避免不必要的类型转换
    if (this.tempWeight !== Number(this.currentWeight)) {
      this.currentWeight = String(this.tempWeight);
    }
    
    // 直接使用布尔值比较
    this.zeroStatus = this.tempWeight <= 10 ? 0 : 1;
  }
},

// 增加beforeDestroy确保清理
beforeDestroy() {
  this.clearInterval();
},

methods: {
  clearInterval() {
    if (this.getWeightAndZeroStatusTimeID) {
      clearInterval(this.getWeightAndZeroStatusTimeID);
      this.getWeightAndZeroStatusTimeID = null;
    }
  }
}
回到顶部