【发布时间】:2011-06-07 17:43:58
【问题描述】:
我有一个对象,只是想在某些事件中销毁它。 XNA中如何调用析构函数?
【问题讨论】:
标签: c# xna destructor
我有一个对象,只是想在某些事件中销毁它。 XNA中如何调用析构函数?
【问题讨论】:
标签: c# xna destructor
将对象设置为null,垃圾收集器将在下一次运行时将其拾取。
附带说明,如果对象是您经常创建的东西(敌人、子弹等),那么您可能希望使用pool 而不是删除该对象。这意味着对象会被回收,因此垃圾收集器的调用频率会降低,从而提高性能。
【讨论】:
null 以及使用pool 的建议是您最不想做的事情? @Nasgharet - 什么不起作用?此外,smokeList 听起来像是一个粒子系统。如果是这种情况,您应该在所有对象上使用池,而不是 null。
XNA)。 IDisposable 模式对于删除当然是有效的,但 OP 并不关心内存删除,而是破坏对象。在实时游戏中(尤其是在 XBox/WP7 上)强制 GC 是粗心的,pooling 仍然比disposing(common objs) 好。从内存的角度来看,没有必要设置为null,但它有帮助当试图从游戏中移除敌人时。子弹什么时候会自动超出范围?
dym对象,直到gameTime对象被释放,因为由事件处理程序创建的强引用。这是事件驱动模型导致的常见问题,因此即使您将其设置为 null,它也不会在 gameTime 被释放之前被释放。
虽然您的里程可能会有所不同,但我更喜欢使用我不再需要的对象 IDisposable 和 Dispose()。这是特别的。当您使用非托管资源时为 true,但设置 Dispose() 声明意图。
请参阅GC.SuppressFinalize 上的此资源,了解如何实现IDisposable 的一个很好的示例。
http://msdn.microsoft.com/en-us/library/system.gc.suppressfinalize.aspx
【讨论】:
将此对象的引用设置为null。
【讨论】:
将对象设置为null后,如果出于某种原因想要立即收集对象,请调用GC.Collect()。
【讨论】:
GC.Collect:“强制立即对所有代进行垃圾收集。”。当然,这一切都取决于是否应该调用GC.Collect。例如。如果一个对象消耗了大量内存,应该尽快释放,GC.Collect很有用。
什么样的对象?如果是 Disposable/IDisposable 你应该调用 object.Dispose() 否则,您可以只使用 object=null,它会被自动“清理”。这不是您正在使用的 C ;)
如果您的“对象”实际上是一个复杂类或其中包含更多对象的东西,您可能需要考虑将其设为 IDisposable 类。
【讨论】:
如果对象包含任何非托管资源,则实现IDisposable(并在完成后使用using 或调用Dispose())。
如果它不包含非托管资源,那么垃圾收集器将在不再引用它时“在某个时候”声明它。
GC.Collect() 将使垃圾收集器进行收集,如果没有对它的引用,它将“销毁”您的对象。这不是一个好主意,因为它会影响性能(它需要时间并将其他对象提升到更高的一代,从而使它们在被回收之前在内存中的持续时间更长)。
为什么需要在某个固定时间销毁对象?
【讨论】:
如果您自己处理清理工作,您要做的是调用GC.SuppressFinalize()...通常您在IDisposable 类中使用GC.SuppressFinalize()。 IDisposable的常用用法见此代码示例:
http://msdn.microsoft.com/en-us/library/system.gc.suppressfinalize.aspx
如果您确实需要立即进行垃圾收集:
var myObj = new MyObject();
// This object will be cleaned up by the Dispose method.
// Therefore, you should call GC.SupressFinalize to
// take this object off the finalization queue
// and prevent finalization code for this object
// from executing a second time.
GC.SuppressFinalize(myObj);
但我提醒你,你真的应该让对象超出范围,让 GC 自然收集对象。只要您不尝试完成它的工作,.NET 运行时在管理内存方面非常有效。
编辑
在查看 cmets 之后,我发现您忘记留下一条重要信息,因为您将相关对象绑定到其他对象方法。这意味着您尝试完成的对象在用于监视事件的方法完成之前不会完成,因此在内存中保留了大约一吨额外的对象。
要打破这个强引用,您可以使用一个名为WeakReference 的对象。或者使用 lambdas 来打破强引用。
有关使用 WeakReference 的示例,请参见此处 http://msdn.microsoft.com/en-us/library/system.weakreference.aspx
或者你可以这样做:
dym.cas += (x, y, z) => gameTime.ElapsedGameTime(x,y,z);
而不是
dym.cas += gameTime.ElapsedGameTime;
【讨论】: