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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > C# >内容正文

C#

C# 内存的理解 通俗说

發布時間:2023/12/4 C# 48 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C# 内存的理解 通俗说 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一.概念

  堆棧是什么?

  在說堆棧之前,先說說內存是神馬?

  內存:程序在運行的過程,電腦需要不斷通過CPU進行計算,這個計算的過程會讀取并產生運算的數據,這些數據需要一個存儲容器存放。這個容器,這就是內存了。

  我們知道C#是強類型語言,每個變量和常量都有一個類型,即所有的數據都會有一個類型。在.Net中,所有的類型又分為值類型和引用類型。簡單介紹一下。

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

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

  值類型和引用類型有什么區別吶?

  主要區別在于值類型對象固定大小,引用類型對象可以指向任何類型,無法確定其大小。因此內存區域分為棧和堆。值類型存儲在棧上,引用類型存儲在堆上。

二.棧和堆

  ? ? ? ? ? ? ? ? ?

      棧:操作系統會為每條線程分配一定的空間,Windows為1M。在棧上的成員不受GC管理器的控制,直接由操作系統分配?;蛘呃斫鉃榇鎯Χ唐谳^小數據塊,超出作用域,自動釋放。

      堆:主要用來存放引用類型對象,不需要我們人工去分配和釋放,由GC管理器托管?;蛘呃斫鉃榇鎯﹂L期較大數據塊,超出作用域并不會被釋放,保持被分配的狀態。GC會處理未引用的堆內存。

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

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

      值類型和引用類型之間可以互轉嗎?

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

          裝箱:

              I.分配堆內存

              II.將值類型的實例字段拷貝到新分配的堆內存中

              III.返回托管堆中新分配的對象的地址在棧中。這個地址就是一個指向對象的引用。

          拆箱:

              I.檢查對象實例,確保它是給定值類型的一個裝箱值。

              II.將該值實例復制到值類型變量中。

三.GC垃圾管理器

   ①GC和堆內存聯系

    上述說到棧是操作系統實時自動分配釋放,不需要我們去管理。堆內存也是由GC控制管理。但是GC并不是實時管理的,是需要通過程序員手動或系統定時觸發的。因為GC是一個耗時的操作,可能在有些系統中觸發的不合時宜(明顯卡頓)。所以,GC也需要優化,需要控制在合事宜的情況觸發。比如游戲中我們需要在切換Loading時觸發GC,而在游戲戰斗中控制不能被觸發。

     因此優化GC,就是優化堆內存,就是盡量減少堆內存,及時回收堆內存。

   ②GC是什么?

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

   ?③GC如何釋放堆內存的?

    GC清理堆時,GC收集器會通過一定的算法清理堆中的對象,并且版本不同算法也不同。標記-壓縮算法:通過一個圖的數據結構來收集對象的根,這個根就是引用地址??梢岳斫鉃?strong>指向托管堆的關系線。當觸發這個算法時,會檢查圖中的每個根是否可達,如果可達,則對其標記,然后在堆上找到剩余沒有標記的對象進行刪除,這樣,

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

    為了優化內存結構,減少在圖中搜索的成本,GC機制又為每個托管堆對象定義了一個屬性,將每個對象分為三個等級,0代,1代,2代。

每當new一個對象的時候,該對象會被定義為第0代,當GC開始回收的時候,先從第0代開始,在這樣一次回收動作之后,0代沒有被回收的對象則被定義為第1代,當回收第1代的時候,第1代中沒有被清理的對象會被定義為第2代。

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

擴展說明:

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

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

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

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

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


總結

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

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