2013-11-28 77 views
1

我很難理解與內存中的對象有關的一些概念,如果有人能讓我走上正確的軌道,我將不勝感激。我意識到管理記憶有多重要,而且我擔心我會採用糟糕的編程習慣。內存中的對象和一般的內存管理

在我的遊戲循環我用lambda表達式的格式如下,從我的遊戲刪除對象:

ObjectsMan.lstExplosionParticles.RemoveAll(particle => particle.TTL <= 0); 

這些對象通常被實例化內部列表中添加方法,例如:

ObjectsMan.EnemyShots.Add(new EnemShot(current.SpritePosition + position.Key, 
Logic_ReturnValue.Angle_TarPlayer(current), position.Value)); 

據我瞭解,該列表正在存儲對象的內存位置。所以當我從列表中刪除它時,對象仍然存在於內存中。那是對的嗎?

如果確實如此,即使我沒有繪製它們,這些坐在內存中的物體是否會導致遊戲滯後(例如,成千上萬的單個拋射物體)?我是否需要手動將每個對象分配給null?

此外,如果我沒有對我的遊戲的繪製方法施加幀速率上限,我是否正確認爲由於人眼無法看到幀而導致我失去了大量性能?

另一個問題是,如果我停止使用調試器並且正在播放聲音,我的聲音驅動程序就會鎖定。我認爲調用我的音效Stop方法會阻止這種情況發生。調試器在停止時繞過XNA的卸載內容方法嗎?這裏發生了什麼?最後,如果我包括額外的使用陳述,我沒有技術上需要,這是否影響我的記憶?例如,我的大多數類都包含一些他們實際上並不需要的使用語句。是否有一個性能相關的理由來清除這個問題,還是僅僅是一個好的編程習慣?

如果有人能給我一些幫助,或者指向正確的方向,我將不勝感激。

謝謝。

+0

所以你有一個包含對象的列表。當對象從列表中刪除時,您不確定在GC啓動之前對象是否會長時間保留在內存中,這是您的擔憂嗎? – ZZZ

+0

這是我的擔心之一,是的。 GC直到節目結束纔開始播放,這是否正確?僅僅因爲我已經從列表中刪除了這些對象,這不應該讓GC有理由將我的對象從內存中刪除?我說錯了嗎? – BeepBeep

回答

3

據我瞭解,該列表正在存儲對象的內存位置。所以當我從列表中刪除它時,對象仍然存在於內存中。那是對的嗎?

是。你只是刪除對象的引用。

如果確實如此,即使我沒有繪製它們,那麼坐在內存中的這些對象中的很多是否會導致遊戲滯後(例如,數千個單個的拋射物體)?

直接?但是,當GC最後開始時,它們會導致滯後。僅僅因爲GC有更多的對象需要照顧。我在Xbox360上遇到了同樣的問題,它沒有代代相關的GC。

我是否需要手動將每個對象分配給null?

這只是刪除參考。與從列表中刪除它相同。

最後,如果我包含額外的使用陳述,我沒有技術上需要,是影響我的記憶?例如,我的大部分類都包含一些他們實際上並不需要的使用語句。是否有一個性能相關的理由來清除這個問題,還是僅僅是一個好的編程習慣?

這裏應該沒有問題。

GC直到程序結束纔會啓動,這是正確的嗎?

錯誤。 GC可以隨時運行。通常,如果應用程序決定內存不足並且操作系統無法提供任何操作,它將運行GC。

僅僅因爲我已經從列表中刪除對象,那不應該讓GC理由從內存中刪除我的對象?

如果此列表僅包含唯一引用,則GC可以自由刪除該對象。但是,如果GC實際上在那個時候運行,那麼它就沒有關係。

另外,通常在編寫遊戲時,應該限制創建的對象的數量。簡單地說,因爲運行GC會產生很多不可預測的滯後。使用結構或重用現有的實例。在粒子系統的情況下,最好的方法是讓每個粒子和場都有結構來表示粒子是否活躍。去除粒子時,只需將該字段設置爲false即可。添加新粒子時,您會首先找到未激活的粒子並設置適當的字段並將其激活。

+0

這非常有幫助,謝謝。我一定會實現你的提示重用對象。 – BeepBeep

+0

您也可以選擇使用GC.Collect()手動調用垃圾回收:http://stackoverflow.com/questions/1149197/gc-collect –