日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) >

C# 内存的理解 通俗说

發(fā)布時(shí)間:2023/12/4 56 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C# 内存的理解 通俗说 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

一.概念

  堆棧是什么?

  在說堆棧之前,先說說內(nèi)存是神馬?

  內(nèi)存:程序在運(yùn)行的過程,電腦需要不斷通過CPU進(jìn)行計(jì)算,這個(gè)計(jì)算的過程會(huì)讀取并產(chǎn)生運(yùn)算的數(shù)據(jù),這些數(shù)據(jù)需要一個(gè)存儲(chǔ)容器存放。這個(gè)容器,這就是內(nèi)存了。

  我們知道C#是強(qiáng)類型語言,每個(gè)變量和常量都有一個(gè)類型,即所有的數(shù)據(jù)都會(huì)有一個(gè)類型。在.Net中,所有的類型又分為值類型和引用類型。簡(jiǎn)單介紹一下。

    值類型:使用int,float,struct,enum關(guān)鍵字直接繼承自System.ValueType定義的類型。

    引用類型:Class,interface,string,delegate繼承自System.Object。

  值類型和引用類型有什么區(qū)別吶?

  主要區(qū)別在于值類型對(duì)象固定大小,引用類型對(duì)象可以指向任何類型,無法確定其大小。因此內(nèi)存區(qū)域分為棧和堆。值類型存儲(chǔ)在棧上,引用類型存儲(chǔ)在堆上。

二.棧和堆

  ? ? ? ? ? ? ? ? ?

      棧:操作系統(tǒng)會(huì)為每條線程分配一定的空間,Windows為1M。在棧上的成員不受GC管理器的控制,直接由操作系統(tǒng)分配。或者理解為存儲(chǔ)短期較小數(shù)據(jù)塊,超出作用域,自動(dòng)釋放。

      堆:主要用來存放引用類型對(duì)象,不需要我們?nèi)斯とシ峙浜歪尫?#xff0c;由GC管理器托管。或者理解為存儲(chǔ)長(zhǎng)期較大數(shù)據(jù)塊,超出作用域并不會(huì)被釋放,保持被分配的狀態(tài)。GC會(huì)處理未引用的堆內(nèi)存。

      不同于值類型直接在棧中存放值,引用類型還需要在棧中存放一個(gè)指向堆中對(duì)象的值的地址。

      值類型,引用類型區(qū)別詳見:https://www.cnblogs.com/u3ddjw/p/6756536.html

      值類型和引用類型之間可以互轉(zhuǎn)嗎?

         這個(gè)需求,是很常見,所以要說一下。答案是肯定的,當(dāng)然可以,這里就需要提到裝箱(值類型===>引用類型),拆箱(引用類型===>值類型)。

          裝箱:

              I.分配堆內(nèi)存

              II.將值類型的實(shí)例字段拷貝到新分配的堆內(nèi)存中

              III.返回托管堆中新分配的對(duì)象的地址在棧中。這個(gè)地址就是一個(gè)指向?qū)ο蟮囊谩?/p>

          拆箱:

              I.檢查對(duì)象實(shí)例,確保它是給定值類型的一個(gè)裝箱值。

              II.將該值實(shí)例復(fù)制到值類型變量中。

三.GC垃圾管理器

   ①GC和堆內(nèi)存聯(lián)系

    上述說到棧是操作系統(tǒng)實(shí)時(shí)自動(dòng)分配釋放,不需要我們?nèi)ス芾怼6褍?nèi)存也是由GC控制管理。但是GC并不是實(shí)時(shí)管理的,是需要通過程序員手動(dòng)或系統(tǒng)定時(shí)觸發(fā)的。因?yàn)镚C是一個(gè)耗時(shí)的操作,可能在有些系統(tǒng)中觸發(fā)的不合時(shí)宜(明顯卡頓)。所以,GC也需要優(yōu)化,需要控制在合事宜的情況觸發(fā)。比如游戲中我們需要在切換Loading時(shí)觸發(fā)GC,而在游戲戰(zhàn)斗中控制不能被觸發(fā)。

     因此優(yōu)化GC,就是優(yōu)化堆內(nèi)存,就是盡量減少堆內(nèi)存,及時(shí)回收堆內(nèi)存。

   ②GC是什么?

     ?GC即(Gabarage Collector,垃圾回收器),歸屬于CLR(公共語言運(yùn)行時(shí),可以理解為.Net虛擬機(jī)),專門用于回收托管堆內(nèi)存的

   ?③GC如何釋放堆內(nèi)存的?

    GC清理堆時(shí),GC收集器會(huì)通過一定的算法清理堆中的對(duì)象,并且版本不同算法也不同。標(biāo)記-壓縮算法:通過一個(gè)圖的數(shù)據(jù)結(jié)構(gòu)來收集對(duì)象的根,這個(gè)根就是引用地址。可以理解為指向托管堆的關(guān)系線。當(dāng)觸發(fā)這個(gè)算法時(shí),會(huì)檢查圖中的每個(gè)根是否可達(dá),如果可達(dá),則對(duì)其標(biāo)記,然后在堆上找到剩余沒有標(biāo)記的對(duì)象進(jìn)行刪除,這樣,

那些不再使用的堆中對(duì)象就刪除了。

    為了優(yōu)化內(nèi)存結(jié)構(gòu),減少在圖中搜索的成本,GC機(jī)制又為每個(gè)托管堆對(duì)象定義了一個(gè)屬性,將每個(gè)對(duì)象分為三個(gè)等級(jí),0代,1代,2代。

每當(dāng)new一個(gè)對(duì)象的時(shí)候,該對(duì)象會(huì)被定義為第0代,當(dāng)GC開始回收的時(shí)候,先從第0代開始,在這樣一次回收動(dòng)作之后,0代沒有被回收的對(duì)象則被定義為第1代,當(dāng)回收第1代的時(shí)候,第1代中沒有被清理的對(duì)象會(huì)被定義為第2代。

    CLR會(huì)為0/1/2代選擇一個(gè)預(yù)算的容量,0代通常為256k-4mb預(yù)算,1代為512-4m,2代不受限制,最大可擴(kuò)充至操作系統(tǒng)的整個(gè)內(nèi)存空間。代數(shù)越長(zhǎng)說明這個(gè)對(duì)象經(jīng)歷了回收的次數(shù)越多,那就意味著該對(duì)象是最不容易被清除的。這種分代的思想將對(duì)象分割成新老對(duì)象,進(jìn)而配對(duì)不同的清除條件,這種巧妙的思想避免了直接清理整個(gè)堆(卡頓后果)。   

擴(kuò)展說明:

 比如Unity采用貝姆垃圾回收機(jī)制與.Net垃圾回收器相比一直有很大的限制。

  I.貝姆垃圾回收:無分代\并行,執(zhí)行時(shí)所有線程阻塞;每次標(biāo)記都會(huì)訪問所有可達(dá)的對(duì)象(窮舉搜索垃圾)。這種方式極有可能在短時(shí)間造成幀率下降,影響玩家體驗(yàn)。

  II.分代回收:效率高很多。

  參考:https://1996v.cnblogs.com/p/9037603.html?from=timeline&isappinstalled=0 

原文地址:https://www.cnblogs.com/guokun/p/11042903.html


總結(jié)

以上是生活随笔為你收集整理的C# 内存的理解 通俗说的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。