日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Dotnet的垃圾回收

發布時間:2023/12/4 编程问答 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Dotnet的垃圾回收 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

最近在做一個項目,用到了大量的非托管技術,所以垃圾回收變得很重要。

?

在說垃圾回收之前,先說說兩個概念:

  • 托管代碼,是由CLR管理的代碼

  • 非托管代碼,是由操作系統直接執行的代碼

在早期C++的時候,內存分配和釋放都是由我們手動處理的,而在公共語言進行時CLR中,多了一個垃圾收集器GC,來充當自動內存管理器,完成同樣的工作。從此,對于開發人員來說,我們可以不需要用顯式的代碼來執行內存管理。這樣做的好處是明顯的:大量相關內存的錯誤被消除了,比方沒有釋放對象導致的內存泄露,或試圖訪問已經釋放的對象的內存,等等。

????為了防止不提供原網址的轉載,特在這里加上原文鏈接:https://abc.com

一、回收和管理托管資源

上面說了,垃圾回收GC在Dotnet中是一個自動的內存管理器,是一種機制,用來清理和回收堆內存中未引用的部分。

通常CLR會在這些情況下啟動垃圾回收:

  • 需要在堆上分配內存給一個新對象,但沒有足夠的空閑內存時;

  • 對象被強制Dispose時;

  • 托管堆上已分配對象的內存超過了閥值(這個閥值會動態調整);

  • 調用了GC.Collect方法

這些內容都是基礎,了解了非常好,面試時有話可說。不了解也沒關系,不會影響做一個好的程序出來。

?

下面的內容如果能記住,倒是對于程序開發很有幫助。

在Dotnet的垃圾回收機制中,回收器會自行優化并適用于多種方案。但是,我們仍然可以根據運行環境來設置垃圾回收的類型。

Dotnet的CLR提供了下面兩種類型的垃圾回收:

  • 工作站垃圾回收

  • 服務器垃圾回收

這兩種回收機制,有一定的區別。

工作站回收,主要是為客戶端應用設計的,也是程序默認的回收機制。垃圾回收的過程,跑在觸發垃圾回收的用戶線程上,并使用相同的優先級。這種方式,優點是不會被掛起或延遲,缺點是需要與其它線程競爭CPU時間。當運行環境中只有一個CPU時,系統會自動采用工作站方式,不管你設置成什么。

服務器回收,針對的是高吞吐的服務器應用,回收過程跑在專用的高優先級線程上,而且默認是多線程在跑,所以效率更高,缺點是占用的資源會更多,而且由于線程之間的干擾和上下文切換,會影響整體性能。

所以,選擇什么樣的回收機制,需要認真分析。通常普通應用,工作站回收就好。如果是服務器端的API服務,需要選擇服務器回收。而如果是在服務端需要啟動多個實例進行處理,比方對總線的數據保存,那還是工作站回收好。

?

設置垃圾回收方式,在開發時,可以在xxx.csproj文件中加入:

<PropertyGroup>?<ServerGarbageCollection>true</ServerGarbageCollection>? </PropertyGroup>

其中,設置true就是服務器模式,設置false就是工作站模式,當然,去掉這一行,默認也是工作站模式。

對于生產環境中已經上線的應用,也可以修改回收模式。找到程序目錄中的xxx.runtimeconfig.json文件,在里面加入:

"configProperties":?{"System.GC.Server":?true }

這兩個配置的關系是:如果開發時在.csproj中加入了ServerGarbageCollection,那在發布時會自動在.runtimeconfig.json中加入System.GC.Server。

二、回收和管理非托管資源

上面說到的回收機制,針對的是托管資源。

對于非托管資源,GC不會主動進行回收?;厥辗峭泄苜Y源,只能手工編寫代碼并顯式的釋放。

通常來說,程序中用到的操作系統的資源文件、網絡或數據庫連接等,都屬于非托管資源,需要手工清理。

有兩種方法可以清理非托管理資源:

  • 使用終結器Finalize,并由GC回收

  • 手動處理Dispose

2.1 使用終結器Finalize

終結器Finalize是System.Object的一個虛方法,這個方法在GC回收對象的內存之前由垃圾回帳調用。我們可以重寫這個方法,來釋放非托管資源。

多說兩句:似乎MS對這個部分有些猶豫,所以這兒規則一直處在兩可之間。C#在析構函數的支持上并不嚴格。System.Object支持重寫Object.Finalize方法,但它創建的類卻不支持,重寫會報錯,而只能通過改寫析構函數來實現,并由編譯器將代碼包裝在try塊中的析構函數或重寫的Finalize中,并由finally調用Object.Finalize來實現。

使用終結器,缺點也是比較明顯的。GC檢測到一個對象需要回收時,會在一段不確定的時間之后調用終結器。這個不確定很討厭,我們很難預料什么時候對象被實際釋放。

Finalize雖然看著是手動清除非托管資源,其實還是由垃圾回收器去做的。它的最大作用是確保非托管資源一定被釋放。

2.2 手動處理Dispose

手動處理最重要的理由,是在需要的時候立即釋放,而不是讓垃圾回收器進行不確定延時后的釋放。

手動釋放,主要的工作是提供一個IDisposable.Dispose的實現,來實現非托管資源的確定性釋放。這樣,當需要釋放時,調用Dispose方法,就會立即釋放非托管資源。

?

手動處理實現起來很簡單??蚣芴峁┝艘粋€接口System.IDisposable:

public?interface?IDisposable?? {??void?Dispose();?? }??

他只包含一個方法Dispose。使用時,需要實現這個方法,在使用完成后及時釋放非托管資源。

同時,Dispose方法還提供了GC.SuppressFinalize方法,來告訴GC對象已經被手動處理,不再需要調用終結器。

public?void?Dispose()?? {??GC.SuppressFinalize(this);?? }?

這種方式下,對象的內存可以做到提前回收。

在某些情況下,可能無法調用IDisposable.Dispose方法來釋放非托管資源,但場景下又確實需要確定性地釋放,這時候可能通過重寫Object.Finalize來實現:

public?class?MyClass???? {????~MyClass()????{//TODO:?釋放未托管的資源}???? }????

有點奇怪,是不是?

其實,這就是上邊我說MS猶豫的地方。如果你直接重寫Object.Finalize,像下面這樣:

public?class?MyClass???? {????protected?override?void?Finalize()????{????//TODO:?釋放未托管的資源}???? }??

編譯時會報錯Do not override object.Finalize. Instead, provide a destructor.,而他正確的寫法,就是析構函數。

?

上面說的內容,做成一個套路模板,就會是這樣的:

public?class?MyClass?:?IDisposable {private?bool?disposedValue;protected?virtual?void?Dispose(bool?disposing){if?(!disposedValue){if?(disposing){//?TODO:?釋放托管狀態(托管對象)}//?TODO:?釋放未托管的資源(未托管的對象)并替代終結器//?TODO:?將大型字段設置為?nulldisposedValue?=?true;}}~MyClass(){Dispose(disposing:?false);}public?void?Dispose(){Dispose(disposing:?true);GC.SuppressFinalize(this);} }

如果你看到了這兒,建議把上面這個套路模板存下來。這算是最完整的一個版本,網上能找到的,大多是簡化版。

?

其實,我們經常使用的很多類,都實現了IDisposable接口。比如說,凡是可以用using來進行調用類,就都實現了IDisposable接口。另外有一些類,把Dispose改成了一個別的名字,比方IO里的Close方法,就是一個Dispose。

另外,如果對象實現了IDisposable接口,而我們直接new了這個對象,那在使用結束后,我們就需要Dispose這個對象。因為既然設計者選擇了Dispose,那結束時調用Dispose就是正確的。

三、總結

最后做個簡單的總結。

垃圾回收模式選擇:應用程序可分配的資源少,或者能夠競爭到的資源少,就使用工作站模式,反之就使用服務器模式。

在回收處理上,托管資源就扔給GC自動處理,非托管資源需要手動處理:

其中:

  • Finalize是標記出非托管資源可被回收,然后由GC去執行回收工作

  • Dispose是直接調用,并即時回收。?

(全文完)

喜歡就來個三連,讓更多人因你而受益

總結

以上是生活随笔為你收集整理的Dotnet的垃圾回收的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 伊人黄色片| 熟妇毛片 | 欧美三区在线 | 先锋影音av资源网 | 日日摸夜夜添狠狠添久久精品成人 | 亚洲特黄一级片 | 中文字幕播放 | 免费欧美视频 | 国产精选在线 | 夜夜操网址 | 久久嗨| 日韩欧美在线一区 | av爱爱网站| 欧美老肥婆性猛交视频 | 看黄色的网址 | 欧美一区一区 | 亚洲国产中文字幕在线 | 狠狠干av| 日韩成人短视频 | 欧美成人一区二区三区高清 | 成人网站免费观看入口 | 最新色网站 | 国产成人免费片在线观看 | 中文字幕第31页 | 欧美一级黄色录像 | 欧美日韩一区二区三区69堂 | 午夜看片| 亚洲一区二区三区精品视频 | 亚洲美女屁股眼交3 | 驯服少爷漫画免费观看下拉式漫画 | 丝袜av网站 | 国产av一区不卡 | 自拍1区| 午夜视频福利网站 | 四虎免费在线观看 | 91视频在线观看网站 | 先锋资源国产 | 老司机免费在线视频 | 91免费网站入口 | 噜噜视频| 免费观看日韩av | 免费看美女隐私网站 | av资源导航 | 乱日视频 | 欧美乱轮视频 | 久久国产一级 | 久艹在线播放 | 日韩一级在线观看 | 青青啪啪 | 香蕉a视频| 影音先锋中文字幕一区二区 | 亚洲色欲色欲www在线观看 | 日本黄色片免费看 | 97成人在线观看 | 国产精品99久久久 | 久久人人爽人人 | 色老板精品凹凸在线视频观看 | 日韩精品免费一区二区 | 777精品久无码人妻蜜桃 | 中文字幕一区二区三区人妻四季 | 亚洲第一免费 | 97人妻精品一区二区三区软件 | 野外吮她的花蒂高h在线观看 | 欧美成人免费观看视频 | 黄网站免费入口 | 日韩黄色片在线观看 | 日本一区视频在线播放 | 欧美少妇诱惑 | 欧美色就是色 | 国产超碰人人爽人人做人人爱 | 大肉大捧一进一出好爽视频动漫 | 久久视频免费看 | 男人和女人搞鸡 | 日本打白嫩屁股视频 | 中文字幕一区二区三区手机版 | 五十路中文字幕 | 亚洲.www | 99成人 | 特大黑人巨交吊性xxxx视频 | 深爱激情站 | 朝桐光在线观看 | 进去里视频在线观看 | 久久狠 | 男男车车的车车网站w98免费 | 欧美激情综合 | 亚洲 国产 欧美 日韩 | 久久一区二区三区四区五区 | 欧美色图13p | 99精品热视频 | 你懂的在线播放 | a免费看 | 午夜在线小视频 | 在线视频一区二区三区 | 成年视频在线播放 | 精品国产无码一区二区 | xxxx毛片 | 成人国产一区 | 免费在线一区二区三区 | 亚洲精品午夜国产va久久成人 |