2015-10-15 37 views
2

由於該進程將被操作系統殺死,並且所有分配的內存都將被回收,是否可以不釋放單元最終化部分中的對象/資源?在單元從內存中卸載之前是否可以不釋放對象(最終化部分)?

例如,

unit Threading; 

interface 

implementation 

    var threadpool: ThreadPool; 

initialization 

    threadpool := ThreadPool.Create; 

finalization 

    threadpool.Free; // is it OK to remove this? 

end. 
+0

如果您試圖在卸載COM組件時避免死鎖,這可能是錯誤的方法 –

+0

我知道..但我真的不知道這個優雅的解決方案,以避免這...迄今爲止,這不會造成麻煩...... –

+0

這是安全的iff ThreadPool只會獲取在進程退出時釋放的資源。記憶是一種資源,但也有很多其他的東西 – Caleth

回答

9

由於該進程將被操作系統殺死,並且所有分配的內存都將被回收,是否可以不釋放單元最終化部分中的對象/資源?

是的,可能。當進程終止時,系統將清理資源。

然而,有幾個限制性條款:

  1. 大多數泄漏檢測工具檢查所有動態分配的內存是由你的過程摧毀它返回控制到系統之前。你提出的做法是使這種工具無能爲力。
  2. 如果您的代碼曾經內置到動態庫(如DLL或程序包)中,那麼可以卸載該庫,同時宿主進程也可以持久化。這是泄漏,可能會影響主機進程的可行性。
  3. 某些對象需要完成,有時需要排序約束。不知道更多關於你的課程,我們不能判斷。
+3

要添加,有些情況可能會有問題。例如,我們自己的軟件在啓動時動態加載字體,並且必須在關機時卸載該字體。如果它沒有正確卸載字體,那麼該字體文件會卡在內存中,直到系統重新啓動。即使強行終止該過程也會導致卡住。然後,如果我們需要替換該字體文件,我們不能。 –

+0

如果這是一個DLL,並且線程池中還有一個線程運行,該怎麼辦? –

+0

@Sebastian確實。如果?將成爲一場災難。 –

5

如果您從定稿部分Free呼叫然後threadpool及其所有子對象將一直存在於你的應用程序的內存泄漏報告。這將很難找到真實然後內存泄漏。

某些對象可能會執行日誌記錄操作或刪除銷燬時的鎖定文件。因此執行所有析構函數可能是必須的。

作爲一個(德爾福)開發人員,你應該總是注意清理堆。否則,你可能會失去對內存管理的控制。它可以讓你或你的公司花費很多錢來控制回來。

1

是的,這是確定的,但:

1)你可以使用然後按照建設:

ThreadPool := ThreadPool.Create; 
RegisterExpectedMemoryLeak(ThreadPool); 

這種方法從單元引用的強制性明令節省你(讓這個單位確實在使用它之前沒有初始化)。

2)否則,您可以零變量(或者,如果你想System.SysUtils依賴使用FreeAndNil):

finalization 
    ThreadPool.Free; 
    ThreadPool := nil; 

這樣你很容易發現,當它釋放誰在訪問線程池。

3)您可以使用TInterfacedObject作爲源類的實現或包裝。