2012-02-07 182 views
0

我有一個主要的對象。它擁有很多包含其他對象的數組。我想知道,當我刪除主對象時,所有的內存都會被釋放(主對象,數組和數組的對象(元素))?例如:當我刪除一個對象時,被刪除的對象是否也被刪除了?

Fruit^ my_fruit = gcnew Fruit; 
Apple^ first_apple = gcnew Apple; 
Apple^ second_apple = gcnew Apple; 
my_fruit->AppleList->Add(first_apple); 
my_fruit->AppleList->Add(second_apple); 

// some operations 

delete my_fruit; // **is it enough to avoid memory leak, is it necessary to delete first and second apple objects?** 

回答

0

由於您的水果和蘋果的目的是通過gcnew實例化,你的清單管理型爲好,你會不會需要調用刪除水果對象;垃圾收集器會照顧它。

另一方面,如果說Fruit對象中的列表是非託管類型,那麼是的,您需要顯式的內存釋放代碼來釋放列表,因爲垃圾回收器不知道或關心爲此分配的內存名單。

最好的做法是爲Fruit類定義一個析構函數,並將刪除列表代碼放在那裏。以水果刪除通話會自動調用析構函數

http://msdn.microsoft.com/en-us/library/248aa748(v=vs.80).aspx

(Matt的修正後編輯)

+0

謝謝,這是有益的..我真的需要了解內存管理。 – user983924 2012-02-07 08:27:27

+0

這是不正確的。刪除不會釋放用gcnew創建的這些託管對象的內存。除非這些類實現IDisposable,否則不需要刪除調用。除非AppleList實現了IDisposable(即它具有析構函數),否則Fruit不需要析構函數。 – 2012-02-07 14:29:57

+0

啊,是的,感到困惑。由於我們正在討論gcnew,它由垃圾收集器處理。另一方面,如果你使用新的代碼,你需要在內存中釋放代碼來防止內存泄漏。 – syclee 2012-02-07 23:31:32

0

刪除通話將釋放內存。使用gcnew分配的內存將被垃圾收集器釋放(而不是您的調用刪除)。調用delete會調用析構函數(這與C#中的Dispose類似)。看到以下內容: http://bytes.com/topic/net/answers/735989-gcnew http://social.msdn.microsoft.com/Forums/en-US/vclanguage/thread/19e35d8c-94c2-4ea0-8e27-8e5cb94e898e/ http://msdn.microsoft.com/en-us/library/ms177197(VS.80).aspx

+0

有什麼方法可以在我想要的時候刪除對象? – user983924 2012-02-07 14:50:31

+0

你爲什麼想要?垃圾收集器會幫你照顧它嗎?如果你使用本地代碼,那麼你將自己控制內存管理。 – 2012-02-07 14:52:59

+0

我不使用本機代碼。我的程序處理了很多數據,所以我不想等垃圾收集器。在大約兩個小時內,我會寫我的代碼並展示給你。可能有關於我的問題。 – user983924 2012-02-07 16:00:38

0

你沒有內存泄漏。通過託管類型,內存被垃圾收集器釋放(正如Matt和sp1ky已經指出的那樣)。 delete關鍵字用於配置的對象。

在列表中使用delete不會處理該列表中包含的任何對象。但是,您並未在列表中使用它,而是在父對象上使用它。所以它取決於是否寫入父對象來自動處理其子對象。

0

除了非常不尋常的程序,垃圾收集「經常發生」,不需要手動釋放對象。你可能遇到的唯一問題是如果你持有大於你需要的大對象的引用。

例如如果您在同一個函數中加載和處理兩個巨大的集合,並將它們存儲在兩個不同的變量中,那麼在處理第二個集合時,保存第一個集合的變量仍然是活動的。如果您實際上不再需要第一個集合,那麼垃圾收集器可能不會注意到,直到您從該函數返回,然後這兩個集合超出範圍。如果這兩個集合不能同時適合內存,這可能不會很快。

你可以做些什麼來解決這個問題,就是試着把你的代碼分解成更小的單元,這樣你就不會堅持引用遠遠超過你需要的東西。有時你不能在不破壞代碼的邏輯結構的情況下做到這一點,但要記住,你總是可以指定一個變量,以便它不再保存對大對象的引用,這將隨後有資格進行垃圾回收。

這有點像手動釋放對象,不同之處在於垃圾回收器負責處理來自該對象的任何其他引用,並且可以用相同的方式對其進行編碼,即使您無法確定是否對象在程序的其他地方是需要的。如果你手動管理內存,你將不得不提出一些策略來傳達對象是否仍然需要,或者保持它「以防萬一」(這將是內存泄漏,就像程序中沒有其他部分一樣使用它,沒人會永遠釋放它)。有了GC,你只需刪除你的參考,如果物體在其他地方需要,它會堅持下去,如果不是,它會很快移除。

相關問題