亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

ASP.Net?Core中的內存和GC機制

 更新時間:2022年03月30日 09:58:47   作者:癡者工良  
這篇文章介紹了ASP.Net?Core中的內存和GC機制,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

托管代碼

在 .NET 中, CLR(Common Language Runtime) 負責提取托管代碼并編譯成機器語言,然后執(zhí)行它。在此過程中,CLR 提供自動內存管理、安全邊界、類型安全等服務,保證了代碼安全。

托管代碼指在其執(zhí)行過程中由 CLR(Common Language Runtime) 管理的代碼,托管代碼是可在 .NET 上運行得一種高級語言(C#、F#等),編寫的托管代碼被編譯后會被生成 中間語言(IL)。

CLR 有 .NET Core/.NET5+、Mono、.NET Framework 等實現,托管代碼生成的文件(IL代碼)不能被操作系統(tǒng)直接運行,需要 CLR 的實現(如 .NET5) 托管運行,托管過程中對其再次編譯生成二進制代碼(JIT編譯)。

中間語言(IL)有時也稱為公共中間語言 (CIL) 或 Microsoft 中間語言 (MSIL)。

自動內存管理

自動內存管理是 CLR 的功能之一,它可以為應用程序管理內存的分配和釋放,托管代碼被執(zhí)行時,由 CLR 進行內存管理,保證了內存安全。

垃圾回收

GC

GC(garbage collector)中文譯為垃圾回收器,.NET 中的 GC 指的是 CLR 中的自動內存管理器,GC 負責管理 .NET 程序的內存分配和釋放。

GC 的優(yōu)點如下:

  • 自動管理內存,不必手動分配和釋放;

  • 高效管理托管堆上的對象;

  • 智能回收對象,清除內存;

  • 內存安全:避免野指針、懸空指針等情況造成嚴重錯誤;

內存

物理內存

物理內存是物理內存條上的內存空間,是物理機器真實的容量大小。

虛擬內存

虛擬內存(Virtual Memory)是計算機操作系統(tǒng)進行內存管理的一種技術,它可以將多個硬件、非連續(xù)地址的碎片空間組合起來,形成進程上可識別的連續(xù)內存空間。

虛擬內存由操作系統(tǒng)進行支持,如 Windows 上的虛擬內存,Linux 上的交互空間,虛擬內存需要操作系統(tǒng)映射到真實的內存地址空間才能使用。虛擬內存調度方式有分頁式、段式、段頁式3種,讀者感興趣可自行查閱資料。

現代操作系統(tǒng)都采用了虛擬內存管理技術,通過對物理存儲設備的抽象,操作系統(tǒng)調度外存當作內存使用,提供了比物理內存更大的內存范圍。

這些存儲設備組成的內存稱為虛擬地址空間,而用戶(開發(fā)者)接觸到的地址是虛地址,并不是真實的物理地址。虛擬空間大大拓展了內存,使得系統(tǒng)可以同時運行多道程序而不“吃力”。

虛擬地址空間分為兩部分:用戶空間、內核空間,每個程序運行時的會消耗兩種空間。在 Linux 中比例是 3:1,在 Windows 中是 2:2。

.NET 內存組成

.NET 中,內存分為非托管內存、托管內存。

.NET Core/.NET5+ 有一個稱為 dotnet 的驅動程序,此驅動程序用于執(zhí)行命令或運行 .NET 程序。當我們使用 dotnet 命令運行一個 .dll 文件時,操作系統(tǒng)會啟動 dotnet 驅動程序,此時會分配操作系統(tǒng)內存資源、dotnet 驅動程序內存資源,這一部分即非托管資源,其中 dotnet 部分的內存包含了 CLR 等部件的內存。即使你并沒有使用到 C/C++ 等非托管代碼或者使用非托管資源,也會使用到非托管內存。

接下來 CLR 將初始化新進程,CLR 將為其分配托管內存(托管堆),這段托管內存是一個連續(xù)的地址空間區(qū)域。.NET 安全代碼只能使用托管內存,不能直接使用物理內存,垃圾收集器會為安全代碼在托管堆上分配和釋放虛擬內存。

顯然, dotnet 的工作原理十分復雜,筆者沒有能力講清楚,感興趣的讀者可以自行查閱資料。

CLR 中的內存

微軟 .NET CLR 文檔中寫道:By default, on 32-bit computers, each process has a 2-GB user-mode virtual address space.

即在 32 位系統(tǒng)中,.NET 進程會使用 2GB 的用戶模式虛擬內存,其虛擬地址空間的表示范圍是 0x00000000 到 0x7fff;而 64 位系統(tǒng)中,地址范圍是 0x000'00000000 到0x7FFF'FFFFFFFF,約等于 16TB。

從以上信息,我們知道 .NET 程序會消耗比較多的虛擬內存,如果在 64 位操作系統(tǒng)上運行 .NET 程序,其用戶模式虛擬地址空間可能遠遠大于 2GB。

編寫一個 "c1" 程序,其代碼如下:

        static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");
            Console.Read();
        }

在 Linux 中使用 dotnet xx.dll 命令運行程序,然后查看其占用的資源:

 VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
  3.1g   0.0g   0.0g S   0.3   0.3   0:00.83 dotnet

使用 dotnet-counters 查看 dotnet 進程:

    GC Heap Size (MB)                                              0
    Gen 0 GC Count (Count / 1 sec)                                 0
    Gen 0 Size (B)                                                 0
    Gen 1 GC Count (Count / 1 sec)                                 0
    Gen 1 Size (B)                                                 0
    Gen 2 GC Count (Count / 1 sec)                                 0
    Gen 2 Size (B)                                                 0
    LOH Size (B)                                                   0

注:使用 dotnet run 運行 .NET 項目,會出現 dotnet、c1 兩個進程,可以看到會產生 dotnet 和 c1 兩個進程,dotnet 是驅動程序,dotnet 啟動后,CLR 會將. dll 程序集編譯,并初始化啟動一個進程。

CLR 中的虛擬地址空間需要位于一個地址塊中,因為在請求虛擬內存分配時,虛擬內存管理器必須找到滿足需求的單個可用塊,例如就算存在大于 2GB 的虛擬地址空間,但如果不是連續(xù)的,則會分配失敗。如果沒有足夠的可供保留的虛擬地址空間或可供提交的物理空間,則可能會用盡內存。

CLR 虛擬內存狀態(tài)

CLR 中的虛擬內存可以有三種狀態(tài):

StateDescription
Free 可用The block of memory has no references to it and is available for allocation. 內存塊沒有對它的引用,可以進行分配
Reserved保留The block of memory is available for your use and cannot be used for any other allocation request. 該內存塊可供您使用,不能用于任何其他分配請求 However, you cannot store data to this memory block until it is committed. 但是,在提交數據之前,不能將數據存儲到此內存塊中
Committed已提交The block of memory is assigned to physical storage. 內存塊已指派給物理存儲

內存分配

CLR 在初始化新進程時,會為進程保留一個連續(xù)的地址空間區(qū)域,這個地址空間被稱為托管堆。托管堆中維護著一個指針,最初此指針指向托管堆的基址,這個指針是向后移動的。當需要分配內存時,CLR 便會分配位于此指針后的內存區(qū)域,同時指針指向此對象地址空間之后的位置。

由于 CLR 通過向指針添加值來為對象分配內存,所以它的分配速度幾乎跟從堆棧中分配內存速度一樣快;而且連續(xù)分配的新對象連續(xù)存儲在托管堆中,程序可以快速地訪問這些對象。

當 GC 回收內存時,一些對象釋放后內存會被回收,這樣托管堆地內存處于碎片化,之后整個內存段會被壓縮,重新組成連連續(xù)的內存段,指針會被重置到對象的末尾。

當然,大對象堆(LOH)回收并不會壓縮內存段,這一點我們后面再討論。

內存釋放

垃圾回收的條件

根據微軟官方文檔,整理的垃圾回收條件如下:

  • 系統(tǒng)物理內存不足;
  • 托管堆分配的內存已超出可接受閾值;(當然,這個閾值會被動態(tài)調整)
  • 手動調用 GC 類的 API(例如 GC.Collect);

托管堆

本機堆(Native Heap)

前面提到過,.NET 的內存有非托管內存和托管內存。CLR 運行的進程,存在本機堆和托管堆兩種內存堆,本機內存堆通過 Windows API 的 VirtualAlloc 函數分配,提供給 操作系統(tǒng)和 CLR 使用,用于非托管代碼所需的內存。

托管堆(Managed Heap)

關于托管堆,前面已經寫了,這里不再贅述。

托管堆代數

托管堆中的內存被分為三代,分別使用0、1、2 標識,GC 分配的內存首先在 0 代托管堆中,當進行垃圾回收時,如果對象沒有被釋放,則將其升級并存儲到 1 代托管堆中。1 代托管堆進行內存回收時,不被釋放的對象也會被升級到 2 代內存中,然后 1 代內存堆進行空間壓縮。

托管堆的管理是 GC 負責的,而 GC 進行內存分配和釋放,使用了 GC 算法。

GC 算法基于以下理論:

  • ① 壓縮托管堆的一部分內存要比壓縮整個托管堆速度快;
  • ② 較新的對象生命周期較短,較舊的對象生命周期較長;
  • ③ 較新的對象趨向于相互關聯,并且大約在同一時間被應用程序訪問;

我們必須深刻理解這些理論,才能深入理解托管堆的設計。

關于 0 到 2 代堆,其基本說明如下:

  • 0 代:0 代中的對象擁有短暫的生命周期,垃圾回收最常發(fā)生在此代中;
  • 1 代:作為生命周期較短和生命周期較長對象的緩沖區(qū)。
  • 2 代:存儲生命周期長的對象;0、1 代沒被回收而升級的對象會升級到 2 代中,靜態(tài)數據等則會一開始就分配到 2代。

在 .NET 5 之前,.NET 有 SOH(小對象堆)、LOH(大對象堆);在 .NET 5 中,出現了 POH ;

小對象堆的內存段有 0、1、2 代堆;

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關文章

  • .NET C#使用微信公眾號登錄網站

    .NET C#使用微信公眾號登錄網站

    這篇文章主要介紹了.NET C#使用微信公眾號登錄網站,教大家利用微信公眾號進行網站登錄,感興趣的小伙伴們可以參考一下
    2016-08-08
  • asp.net 防止用戶通過后退按鈕重復提交表單

    asp.net 防止用戶通過后退按鈕重復提交表單

    經過一番仔細的尋尋覓覓之后,我發(fā)現仍舊無法找出真正能夠完全禁用瀏覽器后退按鈕的辦法。所有這里介紹的方法都能夠在不同程度上、以不同的方式禁止用戶返回前一頁面,但它們都有各自的局限。
    2009-11-11
  • ASP.NET 頁面?zhèn)髦党S梅椒偨Y

    ASP.NET 頁面?zhèn)髦党S梅椒偨Y

    ASP.NET 頁面?zhèn)髦档姆绞接泻芏啵疚恼砹艘恍┍容^常用方法,大家可以根據自己需求自由選擇
    2013-08-08
  • .Net Core靜態(tài)文件資源的使用

    .Net Core靜態(tài)文件資源的使用

    這篇文章介紹了.Net Core靜態(tài)文件資源的使用方法,文中通過示例代碼介紹的非常詳細。對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-07-07
  • 詳解.NET Core 使用HttpClient SSL請求出錯的解決辦法

    詳解.NET Core 使用HttpClient SSL請求出錯的解決辦法

    這篇文章主要介紹了.NET Core 使用HttpClient SSL請求出錯的解決辦法,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2019-03-03
  • ASP.NET下使用WScript.Shell執(zhí)行命令

    ASP.NET下使用WScript.Shell執(zhí)行命令

    ASP.NET下有自己的執(zhí)行CMD命令的方式,這里用WScript.Shell似有畫蛇添足之嫌,但是我們也不能排除真的有機器禁用了.NET的相關類,未雨綢繆嘛。當然也不僅僅局限于WScript.Shell,只要是ASP中能用的組件,統(tǒng)統(tǒng)都可以用于ASP.NET中,而且還更方便!
    2008-05-05
  • asp.net連接數據庫讀取數據示例分享

    asp.net連接數據庫讀取數據示例分享

    這篇文章主要介紹了asp.net連接數據庫讀取數據示例,大家參考使用吧
    2014-01-01
  • asp.net中SqlCacheDependency緩存技術概述

    asp.net中SqlCacheDependency緩存技術概述

    這篇文章主要介紹了asp.net中SqlCacheDependency緩存技術概述,是大型web程序設計中常用的技術,本文對此進行了較為詳細的描述,需要的朋友可以參考下
    2014-08-08
  • .NET?實現啟動時重定向程序運行路徑及?Windows?服務運行模式部署的方法

    .NET?實現啟動時重定向程序運行路徑及?Windows?服務運行模式部署的方法

    這篇文章主要介紹了.NET?實現啟動時重定向程序運行路徑及?Windows?服務運行模式部署,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-09-09
  • ASP.NET服務器控件的生命周期分析

    ASP.NET服務器控件的生命周期分析

    這篇文章主要介紹了ASP.NET服務器控件的生命周期分析,較為詳盡的講述了asp.net服務器控件的運行原理與過程,有助于深入了解asp.net程序的運行原理,需要的朋友可以參考下
    2014-11-11

最新評論