對於 .net 開發人員來說程式的資源管理是必不可少的,要開發出一款優秀的應用就必須明白 .net 的資源管理機制。在 .net 中垃圾**器 gc 幫助我們管理託管資源,在開發時我們不需要過多的關注大多數記憶體問題(例如:記憶體洩漏、dangling pointer)。
零、託管資源
在 .net 中乙個經典的資源管理的例子就是 gc 對迴圈引用的管理。 gc 的 mark and compact 演算法會快速的檢測出由簡單或複雜的關係網所形成的迴圈引用,並把所有不可達的物件是為乙個整體從記憶體中清理出去。 gc 會檢測出和應用程式根物件沒有任何通路相連的物件,然後判定這些物件為不可達物件,接著將這些物件從記憶體中清理出去,最後 gc 將會壓縮託管堆把其中活動的物件放在一起,把空閒的記憶體放在一起形成連續的記憶體區域。簡單地說就是當應用程式不再使用(引用)某個物件時 gc 就會認定這個物件是可**的。
一、非託管資源
前面我們一直在說託管資源,託管資源由 gc 負責因此我們不需要干涉太多,我們需要重點干涉的就是非託管資源。非託管資源包括資料庫連線、 com 物件、 gdi+ 物件以及其他系統物件,這種資源我們如果不加以干涉的話會造成記憶體大量占用,進而程式崩潰作業系統崩潰。
在 .net 中針對非託管資源的控制一共有兩種方法:一種是 finalizer 另一種是 idisposable 。前者的機制存在很多缺陷,因此我們在開發中一般會使用 idisposable 來釋放非託管資源。下面我們來詳細的講解一下為何要選擇後者而不是前者。
一般情況下如果物件存在 finalizer 時 gc 會在判定該物件為垃圾後擇機呼叫 finalizer 。但是 finalizer 並不是及時執行的,也就是說程式在退出臨界區域時,相關的物件(這裡的物件指的時方法、類、窗體等)並不是一執行完就立馬退出,而是會在記憶體中停留一段時間。因此 finalizer 只能保證非託管資源最終可以被釋放,但是不保證在何時釋放。並且大量依賴 finalizer 會降低程式的效能,這是因為垃圾**器需要執行更多的工作才能最終終結這些資源。 gc 清理帶有 finalizer 的垃圾物件是這麼做的:首先 gc 會在每個週期內把包含 finalizer 但還沒有執行的物件放在佇列中,在下乙個週期裡 gc 會清理掉已經執行過 finalizer 的物件,這其中執行物件 finalizer 的執行緒並不是 gc 所在的執行緒。
在這裡需要注意的是具有 finalizer 的物件並不是只存在與乙個週期中,而是有可能存在於多個週期中。.net 為優化垃圾**工作,特意定義了 generation (世代) 這個概念,.net 中一共包含 3個世代,第一次垃圾**之後建立出來的物件叫做 0 代物件,再一次執行垃圾**後依然存在的物件叫做 1 代物件,經過兩次或多次依然存在的物件則叫做 2 代物件。然後世代的存在給具有 finalizer 的物件帶來了我發及時釋放的問題,因為 gc 在每次執行週期都會判斷 0 代物件是不是垃圾,每執行 10 個週期就會判斷一次 1 代物件是不是垃圾,到了 2 代物件這裡則會執行 100 個週期才會判斷一次,因此具有 finalizer 的物件最少需要 gc 執行 10 個週期才會清理,而不具有 finalizer 的物件最多 9 個週期就會被清理。
二、小結
這一篇文章就這麼短,通過這篇文章我們需要注意在需要使用非託管資源的時候優先選擇 idisposable 介面,除非是必須使用 finalizer 。後面的文章我將詳細講解怎麼樣的編碼才能算是具有良好的資源管理的編碼。
MTK資源管理
資源檔案生成的臨時檔案主要有 custmenutree out.c,這個檔案是選單臨時檔案,生成了我們的最終顯示的選單結構。如果你新增的選單沒有顯示,正常顯示的選單突然不顯示了或者顯示錯位了,或者顯示的選單與呼叫的功能不符合了,都可以從這裡查到原因。resource base table.txt這個...
MTK資源管理
使用mtk作開發,常常不可避免和資源打交道,常使用的資源有字串,字型,選單,風格,聲音等,mtk好像沒有系統的專門的資源管理工具,導 致資源管理十分凌亂而容易出問題,雖然有些牛人也開發了一些工具來管理這些資源,但由於使用不便或者其他一些原因,比如資源由大量的巨集控制,以及修改維護 的人多,還有一些其...
linux 資源管理
一 系統資源 網路資源 儲存資源,計算資源 二 系統資源管理名命令 1.檢視目錄下的檔案使用情況 du sh 目錄 檔案 注 du sh檢視的是目錄 檔案占用block塊的大小 ll h檢視檔案 目錄的本身大小 2.檢視檔案系統 格式化好的分割槽 的使用情況 df h 注 檢視檔案系統使用i節點的情...