日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
保持.NET應(yīng)用程序內(nèi)存健康的六個(gè)優(yōu)秀實(shí)踐

本文轉(zhuǎn)載自微信公眾號(hào)「DotNET技術(shù)圈」,作者michael。轉(zhuǎn)載本文請(qǐng)聯(lián)系DotNET技術(shù)圈公眾號(hào)。

成都創(chuàng)新互聯(lián)堅(jiān)持“要么做到,要么別承諾”的工作理念,服務(wù)領(lǐng)域包括:做網(wǎng)站、網(wǎng)站制作、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣等服務(wù),滿足客戶于互聯(lián)網(wǎng)時(shí)代的渾源網(wǎng)站設(shè)計(jì)、移動(dòng)媒體設(shè)計(jì)的需求,幫助企業(yè)找到有效的互聯(lián)網(wǎng)解決方案。努力成為您成熟可靠的網(wǎng)絡(luò)建設(shè)合作伙伴!

大型 .NET 應(yīng)用程序中的內(nèi)存問題是某種無(wú)聲的殺手。有點(diǎn)像高血壓。你可以長(zhǎng)期吃垃圾食品而忽略它,直到有一天你面臨嚴(yán)重的問題。對(duì)于 .NET 程序,該嚴(yán)重問題可能是高內(nèi)存消耗、主要性能問題和徹底崩潰。在這篇文章中,您將看到如何將我們的應(yīng)用程序的血壓保持在健康水平。

你怎么知道你的內(nèi)存使用情況是否健康?你需要做什么來(lái)保持它的健康?這正是本文要討論的內(nèi)容。我們將介紹 6 種最佳做法,以保持內(nèi)存健康并在出現(xiàn)問題時(shí)檢測(cè)問題。您還將看到優(yōu)化垃圾收集并使您的應(yīng)用程序非常快速的最佳實(shí)踐。

1. 應(yīng)盡快收集對(duì)象

為了使您的程序快速運(yùn)行,主要目標(biāo)是盡快收集對(duì)象。要理解為什么它很重要,您需要了解 .NET 的分代垃圾收集器。當(dāng)使用該new子句創(chuàng)建對(duì)象時(shí),它們是在第 0 代的堆上創(chuàng)建的。那是內(nèi)存中非常小的空間。如果在有 Gen 0 集合時(shí)它們?nèi)匀槐灰茫鼈儗⒈惶嵘?Gen 1。Gen 1 是更大的內(nèi)存空間。如果它們?cè)谟械?1 代集合時(shí)仍被引用,則將它們提升到第 2 代。

Gen 0 集合是最頻繁的并且非???。Gen 1 集合涵蓋 Gen 0 內(nèi)存空間和 Gen 1 內(nèi)存空間,并且它們更昂貴。Gen 2 集合包括整個(gè)內(nèi)存空間,包括大對(duì)象堆 (LOH)。它們非常昂貴。GC 已優(yōu)化為具有許多 Gen 0 集合、較少的 Gen 1 集合和很少的 Gen 2 集合。但是,如果您有許多對(duì)象被提升到更高代,那么您將產(chǎn)生相反的效果。這會(huì)導(dǎo)致內(nèi)存壓力[1](又名 GC 壓力)和性能不佳。

順便說(shuō)一下,新對(duì)象的分配非常便宜。您唯一需要擔(dān)心的是集合。

那么如何在低代收集對(duì)象呢?很簡(jiǎn)單,只需確保不會(huì)盡快引用它們即可。有些對(duì)象,比如單例,必須永遠(yuǎn)在內(nèi)存中。沒關(guān)系,它們通常是不會(huì)消耗大量?jī)?nèi)存的服務(wù)。

2. 使用緩存……但要小心

根據(jù)定義,像緩存這樣的機(jī)制很麻煩。這些是長(zhǎng)期存在的臨時(shí)對(duì)象,可能會(huì)升級(jí)到第 2 代。雖然這對(duì) GC 壓力不利,但通常值得付出代價(jià),因?yàn)榫彺娲_實(shí)可以幫助提高性能。但你必須密切關(guān)注它。

緩解部分內(nèi)存壓力的一種方法是使用可變緩存對(duì)象。這意味著不是替換緩存對(duì)象,而是更新現(xiàn)有對(duì)象。這意味著 GC 提升對(duì)象和啟動(dòng)更多 Gen 0 和 Gen 1 收集的工作更少。

這是一個(gè)例子。假設(shè)您正在緩存來(lái)自在線雜貨店的庫(kù)存商品。您有一個(gè)緩存機(jī)制來(lái)存儲(chǔ)經(jīng)常查詢的項(xiàng)目的價(jià)格和數(shù)據(jù)。就像那些會(huì)導(dǎo)致高血壓的冷凍比薩餅。假設(shè)每 5 分鐘您必須使緩存無(wú)效并重新查詢數(shù)據(jù)庫(kù),以防細(xì)節(jié)發(fā)生變化。因此,在這種情況下,不是創(chuàng)建新Pizza對(duì)象,而是更改現(xiàn)有對(duì)象的狀態(tài)。

3. 留意 GC 中的時(shí)間百分比

如果您想知道垃圾收集對(duì)執(zhí)行時(shí)間的影響有多大,這很容易做到。簡(jiǎn)單看看性能計(jì)數(shù)器.NET CLR Memory | % GC 時(shí)間。這將顯示垃圾收集器使用了百分之多少的執(zhí)行時(shí)間。有許多工具可以查看性能計(jì)數(shù)器。在 Windows 中,您可以使用 PerfMon。在 Linux 中,您可以使用dotnet-trace[2]。要了解更多信息,請(qǐng)查看我的文章Use Performance Counters in .NET to measure Memory, CPU, and Everything[3]。

我將給您一些神奇的數(shù)字,但請(qǐng)注意這些數(shù)字,因?yàn)橐磺卸加衅渥陨淼谋尘?。?duì)于大型應(yīng)用程序,10% 的 GC 時(shí)間可能是一個(gè)健康的百分比。GC 中 20% 的時(shí)間處于臨界狀態(tài),任何更多都意味著您有問題。

4. 留意那些 Gen 2 Collections

除了 GC 中的時(shí)間百分比,您應(yīng)該監(jiān)控的另一個(gè)重要指標(biāo)是 Gen 2 收集的數(shù)量?;蛘吒_切地說(shuō)是第 2 代收藏的速度。目標(biāo)是盡可能少地使用它們。考慮到這些是完整的內(nèi)存堆集合。當(dāng) GC 收集所有內(nèi)容時(shí),它們有效地凍結(jié)了應(yīng)用程序的所有線程。

對(duì)于您應(yīng)該擁有多少 Gen 2 系列,我無(wú)法給出一個(gè)神奇的數(shù)字。但我建議每隔一段時(shí)間積極監(jiān)控這個(gè)數(shù)字,如果比率上升,那么你可能會(huì)添加一些非常糟糕的行為。您可以通過(guò)性能計(jì)數(shù)器.NET CLR Memory |查看該數(shù)字。% Gen 2 集合

PerfMon 顯示第 2 代集合

5. 監(jiān)控穩(wěn)定的內(nèi)存消耗

考慮應(yīng)用程序的常規(guī)狀態(tài)。有些事情一直在發(fā)生。它可能是一個(gè)服務(wù)請(qǐng)求的服務(wù)器,一個(gè)從隊(duì)列中提取消息的服務(wù),一個(gè)有很多屏幕的桌面應(yīng)用程序。在此期間,您的應(yīng)用程序不斷創(chuàng)建新對(duì)象,執(zhí)行一些操作,然后釋放這些對(duì)象并返回到正常狀態(tài)。這意味著從長(zhǎng)遠(yuǎn)來(lái)看,內(nèi)存消耗應(yīng)該或多或少相同。當(dāng)然,它可能會(huì)在高峰時(shí)間或繁重操作期間達(dá)到高水平,但一旦完成它應(yīng)該會(huì)恢復(fù)正常。

但是,如果您監(jiān)控了許多應(yīng)用程序,您可能知道有時(shí)內(nèi)存會(huì)隨著時(shí)間的推移而增加。內(nèi)存的平均消費(fèi)緩慢上升到更高的水平,即使它在邏輯上不應(yīng)該。這種行為的原因幾乎總是內(nèi)存泄漏[4]。這是一個(gè)對(duì)象不再使用的現(xiàn)象,但由于某種原因,它仍然被引用,因此從未被收集。

當(dāng)一個(gè)操作導(dǎo)致對(duì)象泄漏時(shí),每個(gè)這樣的操作都會(huì)消耗更多的內(nèi)存。隨著時(shí)間的推移,記憶力上升。當(dāng)足夠的時(shí)間過(guò)去時(shí),內(nèi)存接近其極限。在 32 位進(jìn)程中,該限制為 4GB。在 64 位進(jìn)程中,它取決于機(jī)器約束。當(dāng)我們?nèi)绱私咏鼧O限時(shí),垃圾收集器就會(huì)恐慌。它開始為每個(gè)其他分配觸發(fā)全內(nèi)存第 2 代收集,以免內(nèi)存不足。這很容易使您的應(yīng)用程序變慢。當(dāng)更多的時(shí)間過(guò)去時(shí),內(nèi)存確實(shí)達(dá)到了它的極限,并且應(yīng)用程序會(huì)因?yàn)?zāi)難性的OutOfMemoryException. 你有它 - 相當(dāng)于心臟病發(fā)作。

為了確保您不會(huì)達(dá)到這種狀態(tài),我的建議是隨著時(shí)間的推移主動(dòng)監(jiān)控內(nèi)存消耗。最好的方法是查看性能計(jì)數(shù)器Process | Private Bytes。您可以使用Process explorer[5]或 PerfMon輕松完成。

6. 定期查找內(nèi)存泄漏

內(nèi)存問題的#1 罪魁禍?zhǔn)缀翢o(wú)疑問是內(nèi)存泄漏。很容易造成它們,它們可以被長(zhǎng)期忽視,最終會(huì)造成大量損害。在應(yīng)用程序持續(xù)崩潰的階段修復(fù)內(nèi)存泄漏非常困難。您必須更改可能導(dǎo)致各種回歸錯(cuò)誤的舊代碼。因此,我將為具有健康內(nèi)存的應(yīng)用程序添加第二個(gè)主要目標(biāo):修復(fù)并避免內(nèi)存泄漏。

期望您的團(tuán)隊(duì)永遠(yuǎn)不會(huì)引入內(nèi)存泄漏是不現(xiàn)實(shí)的。并且在每次新提交時(shí)檢查整個(gè)應(yīng)用程序中的內(nèi)存泄漏是不切實(shí)際的。相反,我建議添加每隔一段時(shí)間檢查內(nèi)存泄漏的做法,它可能是每周、每月或每季度,具體取決于你的需求。

一種方法是在每次看到內(nèi)存上升時(shí)檢查內(nèi)存泄漏(如提示 #5 中建議的那樣)。但問題是內(nèi)存占用低的泄漏也會(huì)導(dǎo)致很多問題。例如,您可能有一些本應(yīng)收集但仍處于活動(dòng)狀態(tài)的對(duì)象,并且仍有代碼在其中執(zhí)行,這會(huì)導(dǎo)致不正確的行為。

檢測(cè)和修復(fù)內(nèi)存泄漏的最佳方法是使用內(nèi)存分析器。在我的文章Demystifying Memory Profilers in C# .NET Part 2: Memory Leaks 中[6]了解如何做到這一點(diǎn)。

要了解哪種設(shè)計(jì)會(huì)導(dǎo)致內(nèi)存泄漏,請(qǐng)查看我的文章.NET 中可能導(dǎo)致內(nèi)存泄漏的 8 種方式[7]。

總結(jié)

所以你有它,一個(gè)健康記憶狀態(tài)的秘訣。如果您遵循這些建議,您的應(yīng)用程序?qū)⒑芸觳⑶蚁暮苌俚膬?nèi)存。但說(shuō)真的,請(qǐng)吃健康的食物和鍛煉??

References

[1] 內(nèi)存壓力: https://michaelscodingspot.com/avoid-gc-pressure/

[2] dotnet-trace: https://github.com/dotnet/diagnostics/blob/master/documentation/dotnet-trace-instructions.md

[3] Use Performance Counters in .NET to measure Memory, CPU, and Everything: https://michaelscodingspot.com/performance-counters/

[4] 內(nèi)存泄漏: https://michaelscodingspot.com/ways-to-cause-memory-leaks-in-dotnet/

[5] Process explorer: https://docs.microsoft.com/en-us/sysinternals/downloads/process-explorer

[6] Demystifying Memory Profilers in C# .NET Part 2: Memory Leaks 中: https://michaelscodingspot.com/memory-profilers-for-memory-leaks/

[7] .NET 中可能導(dǎo)致內(nèi)存泄漏的 8 種方式: https://michaelscodingspot.com/ways-to-cause-memory-leaks-in-dotnet/


分享名稱:保持.NET應(yīng)用程序內(nèi)存健康的六個(gè)優(yōu)秀實(shí)踐
網(wǎng)頁(yè)URL:http://www.dlmjj.cn/article/djpjjsi.html