1. 程式人生 > >C# CLR via 對象內存中堆的存儲【類型對象指針、同步塊索引】

C# CLR via 對象內存中堆的存儲【類型對象指針、同步塊索引】

一個表 style bsp 同步 spa .net clr 以及 不知道

最近在看書,看到了對象在內存中的存儲方式。

講到了對象存儲在內存堆中,分配的空間除了類型對象的成員所需的內存量,還有額外的成員(類型對象指針、 同步塊索引 ),看到這個我就有點不懂了,不知道類型對象指針是什麽,指向的什麽?

從網上找也沒有找到,最後往下看,書中有些描述。說下我的理解:

類型對象指針:指向類型對象存儲的地址,假如有一個類型Person,它在堆中有一塊區域存儲它內部的字段和成員以及兩個額外成員(類型對象指針、 同步塊索引 ),類型對象的類型對象指針指向的是System.Type的地址。

因為Person類型在內存中相對於System.Type也是作為一個對象存在的,System.Type類型也是一個類型對象,它的類型對象指針指向本身;

實例化一個Person對象,Person p = new Person(); p對象在內存堆中也分配一塊區域存儲它內部的字段和成員以及兩個額外成員(類型對象指針、 同步塊索引 ),p的類型對象指針指向Person類型在堆中的地址。

同步塊索引:先說一下同步塊,.NET團隊在設計基本框架時充分考慮了線程同步的問題,其結果就是.NET為每一個堆內對象都提供了支持線程同步的功能,這就是同步機制的雛形【參考:http://genwoxuedotnet.blog.51cto.com/1852748/504107】

但是對每個堆內對象都分配同步塊有一個較大的弊端,就是這樣增大了內存的消耗。在一般的系統中,需要同步機制支持的對象可能只占少數,這樣對於大多數對象來說,一個同步塊的內存消耗就完全被浪費了。鑒於這一點,.NET框架采用了一種折中的辦法,就是實際只為每個堆內對象分配一個同步索引,該索引中只保存一個表明數組內索引的整數。.NET在加載時會新建一個同步塊數組,當某個對象需要被同步時,.NET會為其分配一個同步塊,並且把該同步塊在同步塊數組中的索引加入該對象的同步塊索引中。

同步塊機制包含如下的幾點:
· 在.NET被加載時初始化同步塊數組。
· 每一個被分配在堆上的對象都會包含兩個額外的字段,其中一個存儲類型指針,而另外一個就是同步塊索引,初始時被賦值為-1。
· 當一個線程試圖使用該對象進入同步時,會檢查該對象的同步索引。如果索引為負數,則會在同步塊數組中尋找或者新建一個同步塊,並且把同步塊的索引值寫入該對象的同步索引中。如果該對象的同步索引不為負值,則找到該對象的同步塊並且檢查是否有其他線程在使用該同步塊,如果有則進入等待狀態,如果沒有則申明使用該同步塊。

同步塊是指.NET維護的同步塊數組中的某個元素

C# CLR via 對象內存中堆的存儲【類型對象指針、同步塊索引】