2012-12-03 118 views
2

我想弄清楚什麼時候python對象是垃圾收集的候選人。我已經閱讀了一些文件/帖子,一直未能找到明確的答案。什麼時候python對象是垃圾收集的候選對象?

舉例如下一行。這是foo的最後一個參考。 foo指向的對象何時可用於垃圾收集?

ret = func(['xyz: ' + foo.name]) 

斷裂下來的(可能的)各個步驟:創建

  1. 臨時參考名稱。
  2. 'xyz:'與名稱和值連接返回。
  3. 列表是使用新字符串創建的。
  4. 函數被調用新數組。
  5. 函數返回。
  6. 結果被分配給ret。
  7. 下一個指令......

之間其中在物先資格被收集兩步?對象的引用計數何時遞減?

如果步驟列表不完整/不正確,請讓我知道。我只是試圖列舉它們給出可能的參考答案的共同起點。

+1

這裏沒有陣列。有一個列表。 –

+1

您可能會發現這個PyCon講話很有用 - 他談論了PyCon垃圾回收模型以及如何調試和分析Python的內容:http://www.youtube.com/watch?v=6jD34p8PokU –

+0

謝謝@RachelSanders!本視頻將回答這個問題。如果你想提供答案,我會標記它。這裏是特定時間的鏈接。 http://www.youtube.com/watch?feature=player_detailpage&v=6jD34p8PokU#t=1020s – Dillon

回答

1

變量會盡快把它的所有引用超出範圍或被手動刪除(del x)有資格進行垃圾回收。

在您的示例中,foo必須存在於此行之前(否則它是NameError),因此將永遠不會在您的示例代碼塊中進行垃圾回收,因爲在此之後引用仍然存在。即使有人在此之後調用del foo,我們也不得不假定沒有其他地方的對象被引用來收集垃圾。

+0

可以顯示一個對象有資格進行垃圾回收(或不回收),而不會對任何特定的垃圾回收器進行任何說明或是否會實際收集垃圾回收器。 – delnan

+0

@delnan好點,編輯。 –

+0

我問這個問題的原因是因爲我看到在第7步之前收集了對象(__del __()被調用)。這是相當意想不到的,這就是爲什麼我質疑它何時首次有資格收集。 要清楚,我不在乎何時實際收集,而是何時首先是候選人。 – Dillon

5

與其他垃圾收集語言一樣,經驗法則是:無法訪問時。這意味着,只要程序(它的任何部分)仍然可以訪問它,就不能使用它。之後,這是公平的比賽。當(甚至是否實際上是回收完全是由實施。

在你的榜樣,名稱foo保持對象活着,因爲程序仍然可以使用它在後面的語句。 (理論上,一個實現可能會檢測到一個變量是否不再被使用,並刪除該引用 - 可能會使對象無法及時更新。實際上,這在Python中是不可能的,除了可能由JIT編譯器編譯的一些痕跡。)列表,相反,如果func未在某些可到達的位置(例如,可到達對象的屬性或全局變量)中存儲對它的引用,則執行func或甚至在此期間可能變得無法訪問。

你混淆了 foo,它指的是物體,推理垃圾收集時,這是致命的

注意。沒有對象foo,只有一個對象foo在給定的時間點(以及它在不同時間點引用的一組對象)引用。這一點很重要:

  • foo可以改變爲指向另一個對象,並將它原指有可能成爲不可達的對象。除非你區分這兩種情況,否則你不能談論這種情況。
  • 對象foo可能有許多其他參考指向(實際上很可能)。有可能在foo超出範圍之後很長時間保持對象存活,被送入del或更改爲引用另一個對象。
+0

你是對的,澄清的foo是對所討論對象的引用。 – Dillon