antvis / G

💥 A flexible rendering engine for visualization.

Home Page:https://g.antv.antgroup.com/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[g]使用antv/g的动画会造成内存泄露

coredesign1234 opened this issue · comments

使用ant/g的lottie功能和动画功能,但是会出现严重的内存泄露,如下string会留在内存中无法释放

import { loadAnimation } from '@antv/g-lottie-player';
import { LottieAnimation } from '@antv/g-lottie-player/dist/LottieAnimation';
import ServiceConnectingAnimationJson from '../../../../res/service_connecting_animation.json';
const serviceConnectingAnimation_ = loadAnimation(ServiceConnectingAnimationJson as any, { loop: true, autoplay: true });
const radarWaveAnimationWwrapper = serviceConnectingAnimation_.render(this);
radarWaveAnimationWwrapper.scale(0.25);
radarWaveAnimationWwrapper.translate(- 28 / 2, - 28 / 2);

在适当时刻调用销毁代码:

serviceConnectingAnimation_.destroy();

但是会有大量的动画string留在内存之中,如如下字符串

translate(209.00000000000003px,214.00000000000003px) scalex(0.023794634822723155) scaley(0.023794634822723155)

而且经常一夜会造成几G的内存泄露
在代码中,这些字符串被如下代码中的cache引用

function memoize(func, resolver) {
    if (typeof func !== 'function' ||
        (resolver != null && typeof resolver !== 'function')) {
        throw new TypeError('Expected a function');
    }
    var memoized = function () {
        var args = [];
        for (var _i = 0; _i < arguments.length; _i++) {
            args[_i] = arguments[_i];
        }
        var key = resolver ? resolver.apply(this, args) : args[0];
        var cache = memoized.cache;
        if (cache.has(key)) {
            return cache.get(key);
        }
        var result = func.apply(this, args);
        memoized.cache = cache.set(key, result) || cache;
        return result;
    };
    memoized.cache = new (memoize.Cache || Map)();
    return memoized;
}
memoize.Cache = Map;

最小可复现demo如下
https://codesandbox.io/p/sandbox/dan-huang-lottie-l6fz3t?file=%2Findex.js

确实,这里不适合使用 memoize,无法清空 cache

@xiaoiver 有临时的解决方案么?

@xiaoiver 有临时的解决方案么?

我想到的方案是保留 transform 中的一定精度,减少动画过程中产生的 transform string 数量。修复中预计今天发布。

@xiaoiver 好的,这样应该能缓解一下
不过还是看看根除下

https://codesandbox.io/p/sandbox/dan-huang-lottie-l6fz3t?file=%2Findex.js

另外我用这个例子测了一下:https://l6fz3t.csb.app/

间隔 5 分钟快照,OOM 似乎不是很明显?你也是用这个例子度量的嘛
截屏2024-01-10 上午10 56 04

其中部分会释放,但是我们的场景会播放一夜,就会很明显了
我们的业务代码,实际上是多个组件同时在播放动画,demo只是剥离了其中一个组件

其中部分会释放,但是我们的场景会播放一夜,就会很明显了 我们的业务代码,实际上是多个组件同时在播放动画,demo只是剥离了其中一个组件

了解我会在动画过程中禁用掉 memoize,否则会创建大量 CSSUnitValue 造成 OOM,大量插值也无法命中缓存:

截屏2024-01-10 下午2 19 46

升级到 @antv/g@5.18.24 即可