0

为了防止 ActionScript 3.0 中的内存泄漏,我在必须使用向量的类中使用成员向量,例如:

public class A
{
    private var mHelperPointVector:Vector.<Point> = new Vector.<Point>();


    public static GetFirstData():Vector.<Point>
    {
        mHelperPointVector.length = 0;
        ....
        return mHelperPointVector;
    }


    public static GetSecondData():Vector.<Point>
    {
        mHelperPointVector.length = 0;
        ....
        return mHelperPointVector;
    }
}

然后我有使用 GetFirstData 和 GetSecondData 方法的消费者,存储对这些方法返回的向量的引用,例如:

public function OnEnterFrame():void
{
    var vector:Vector.<Point> = A.GetSecondData();
    ....
}

这个技巧似乎很好,但有时我需要在一段时间后处理 GetSecondData() 返回的向量,在这种情况下,这个向量会被另一个调用 GetSecondData() 或 GetFirstData() 覆盖......解决方案是将向量复制到新向量......但在这种情况下最好完全避免这个技巧。你如何处理这些问题?我必须使用大量向量(每个向量的长度在 1-10 之间)。

4

1 回答 1

0

关于垃圾收集的事情只是尽量避免实例化(和处置)。很难说什么是最好的方法,因为我看不到你如何/为什么使用你的 Vector 数据,但乍一看,我认为你的方法会不断丢失数据(你几乎创建等效的弱实例,因为它们很容易被覆盖)并更改 Vector 的长度并不能真正避免垃圾收集(它可能会延迟和减少垃圾收集,但您仍然会不断地丢弃数据)。

坦率地说,我认为点向量不会发生内存泄漏,除非您泄漏对左右向量的引用。在这种情况下,最好修复这些剩余的引用,而不是简单地提出一个解决方案来重用相同的向量(这可能会产生更多的不利影响)。

但是,如果您真的关心内存,我认为您最好的解决方案是提前创建您需要的所有向量(如果它是一个固定数字并且您提前知道它们的长度),或者更好的是,使用对象池. 后者肯定是一个更强大的解决方案,但它需要在您的端进行一些设置,包括创建一个 Pool 类,然后在使用它时。将其放入代码中,一旦实现,它将像这样使用:

// Need a vector with length of 9
var myVector:Vector.<Point> = VectorPool.get(9);

// Use the vector for stuff
...

// Vector not needed anymore, put it back in the pool
VectorPool.put(myVector);
myVector = null; // just so it's clear we can't use it anymore

VectorPool将控制您拥有的向量列表,让代码的其他部分根据需要“借用”向量(其中它们将在 VectorPool 中被标记为“已使用”)并将它们归还(将它们标记为未使用)。get()如果未使用的对象列表中没有可用的向量,您的代码还可以根据需要在现场(内部)创建向量;这将使其更加灵活(在某些情况下不推荐,因为您仍在花时间进行实例化,但在这种情况下可能可以忽略不计)。

这是一个非常宏观的解释(您仍然必须编写VectorPool),但是像这样的对象池被认为是避免重新实例化以及对即将被重用的对象进行垃圾收集的最终解决方案。

作为参考,这是我用作非常通用的对象池的内容: https ://github.com/zeh/as3/blob/master/com/zehfernando/data/ObjectPool.as

或者更专业的一个,当我需要一堆BitmapData类似大小的一次性实例时,我会使用它: https ://github.com/zeh/as3/blob/master/com/zehfernando/data/BitmapDataPool.as

我相信在您需要的模具中实现 VectorPool 类将类似于上面的链接。

作为旁注,如果性能是一个问题,我建议也使用固定长度的向量,例如

// Create a vector of 9 items, filled with `nulls`
var myPoints:Vector.<Point> = new Vector.<Point>(9, true);

这使它更快,因为随着时间的推移您不会有微分配。您必须直接设置项目,而不是使用push()

myPoints[0] = new Point(0, 0);

但这实际上是一个强制优势,因为设置向量项比push().

于 2013-10-07T21:08:19.117 回答