2013-10-07 86 views
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之间)。

+0

大小为10的两个向量不应该是一个问题。我想象分配/创建新向量并填充值的问题,但希望看到更多的代码(需要测试的基本工作示例)才能确定。作为一个想法,当你做GetFirstData时,你的类A可以有一个布尔标志来检查它是否应该清除以前的数据。另外,还有一些脱离主题,请看Object Pools。 –

回答

1

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

坦率地说,不要认为你会有点矢量的内存泄漏,除非你泄漏了向左和向右的引用。在这种情况下,最好修复这些剩余的引用,而不是简单地提出一个解决方案来重用相同的向量(可能会产生更多的不利影响)。但是,如果你真的真的关心内存,我认为你最好的解决方案是要么提前创建所有你需要的向量(如果它是一个固定的数字,并且你知道它们的长度),或者,更好的是,使用Object Pools。后者肯定是一个更强大的解决方案,但它需要一些设置,无论是通过创建一个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()更快。