【问题标题】:Freeing memory of ThreeJS application释放 ThreeJS 应用程序的内存
【发布时间】:2017-11-02 11:05:49
【问题描述】:

我目前在 ThreeJS 应用程序中释放内存时遇到问题。

我知道已经有几个关于这个问题的问题:

确实使用我制作的以下 Typescript 函数处理我的对象:

function dispose( object3D: THREE.Object3D ): void
{
    // Dispose children first
    for ( let childIndex = 0; childIndex < object3D.children.length; ++childIndex )
    {
        this.dispose( object3D.children[childIndex] );
    }

    object3D.children = [];

    if ( object3D instanceof THREE.Mesh )
    {
        // Geometry
        object3D.geometry.dispose();

        // Material(s)
        if ( object3D.material instanceof THREE.MultiMaterial )
        {
            for ( let matIndex = 0; matIndex < object3D.material.materials.length; ++matIndex )
            {
                object3D.material.materials[matIndex].dispose();
                object3D.material.materials[matIndex] = null;
            }
            object3D.material.materials = [];
        }

        if ( object3D.material.dispose )
        {
            object3D.material.dispose();
            object3D.material = null;
        }
    }

    // Remove from parent
    if ( object3D.parent )
        object3D.parent.remove( object3D );

    object3D = null;
}

但是,当我使用 Chrome 开发工具做堆快照时,我仍然有很多:

  • 数组
  • Vector2(__directGeometry 中的紫外线,...)
  • Vector3(geometry 中的顶点,faces 中的法线,faces 中的顶点颜色,...)
  • Face3(geometry 中的人脸)
  • 颜色(__directGeometry 中的颜色,...)
  • JSArrayBufferData(颜色,正常,在attributes of geometry,...)

由于内存中的所有数据,我的应用程序在 iOS 上被 Jetsam 杀死,请参阅:Jetsam kills WebGL application on iOS

我怀疑库中的某些数据在我要求时没有释放。

【问题讨论】:

  • 这听起来更像是 Jetsam 过于激进了。 JavaScript 是垃圾回收的,因此在释放对象后立即拍摄堆快照可能无法 100% 反映 GC 后的内存状态。物体是否会消失(比如 1 分钟后)?如果没有,那么代码中可能还有其他对它们的引用没有被释放,因为GC只能在没有引用的情况下收集一个对象。
  • 不幸的是,它们似乎仍在内存中,即使在 1 分钟之后(这是相当长的时间,我认为 GC 会更频繁地完成它的工作)。 there may be other references to them in the code which have not been released,是的,这就是为什么那些对象不会从内存中清除的唯一原因。 @TheJim01:你知道是否有一种“简单”的方法可以在代码中“标记”一个对象,以便在 Chrome 开发工具中轻松检索它,以便我可以看到它的引用位置?
  • 遗憾的是,我不知道有什么简单的方法可以找到参考资料。如果你发现了,请告诉我! :) 除此之外,我会将问题简化为最简单的形式:编写一个非常简单的仅 JavaScript 应用程序(没有 TypeScript),看看它是否以相同的方式执行。如果是这样,那么我不确定你还能做什么。
  • 我相信你正在寻找这个:stackoverflow.com/a/33199591/1980846
  • @gaitat : 提供的 dispose 函数和我的一样,除了它也会处理地图,但这对我来说不是问题。

标签: javascript memory three.js


【解决方案1】:

尝试处理所有内容。我正在使用这个 sn-p 一段时间。它处理材料、纹理、3d 对象。它遍历数组和普通对象。

let dispose = function(o) {
    try {
        if (o && typeof o === 'object') {
            if (Array.isArray(o)) {
                o.forEach(dispose);
            } else
            if (o instanceof THREE.Object3D) {
                dispose(o.geometry);
                dispose(o.material);
                if (o.parent) {
                    o.parent.remove(o);
                }
                dispose(o.children);
            } else
            if (o instanceof THREE.Geometry) {
                o.dispose();
            } else
            if (o instanceof THREE.Material) {
                o.dispose();
                dispose(o.materials);
                dispose(o.map);
                dispose(o.lightMap);
                dispose(o.bumpMap);
                dispose(o.normalMap);
                dispose(o.specularMap);
                dispose(o.envMap);
            } else
            if (typeof o.dispose === 'function') {
                o.dispose();
            } else {
                Object.values(o).forEach(dispose);
            }
        }
    } catch (error) {
        console.log(error);
    }
};

【讨论】:

    猜你喜欢
    • 2017-02-15
    • 1970-01-01
    • 2010-09-26
    • 2013-08-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-16
    相关资源
    最近更新 更多