Object型別占用多大記憶體?

2021-06-16 13:55:50 字數 2945 閱讀 2499

object佔多少記憶體,誰也不知道,按照非託管的想法是,如果你只定義乙個類,而它沒有任何資料成員,我在vs2008下,使用預設位元組對齊, 

class object

; 這樣得出來 sizeof( object ) 為 1。

在c#裡,是不能直接獲取object占用記憶體大小的,因為它根本不是乙個標準的布局。

而樓上的binaryformatter的方法,只是以二進位制格式將物件或整個連線物件圖形序列化和反序列化。它甚至還有可能包含版本資訊,所以它的結果並不能代表乙個物件所占用記憶體的大小。

c#提供了一種可以獲取乙個物件的非託管記憶體的大小的方法。但是必須在顯式指定了記憶體布局以及位元組對齊等資訊的物件上才可以使用。

現在我們定義如下物件:

[structlayout( layoutkind.sequential )]

public class myobject

,大家都知道,所有的物件都是從myobject繼承而來的,也就是說,我們上面這個myobject類,也隱含的繼承了object。

那麼,現在我們看看這段**:

int size = marshal.sizeof( typeof( myobject ) );

執行結果是1。

看來跟c++是一樣的。也就是說,乙個未定義任何資料成員的空物件,其占用1位元組的記憶體。

那麼我們再來看看一些標準成員的大小,比如int,long,double等。

int size = marshal.sizeof( typeof( int ) ); //結果為4

int size = marshal.sizeof( typeof( long ) ); //結果為8

int size = marshal.sizeof( typeof( float ) ); //結果為4

int size = marshal.sizeof( typeof( double ) ); //結果為8

可見,這些基本資料型別,與非託管下的大小是沒有區別的。

那麼現在我們來看看混合在一起的情況。

[structlayout( layoutkind.sequential )]

public class mydataobject

然後我們執行 int size = marshal.sizeof( typeof( mydataobject ) );

會發現結果是24。

為什麼是24呢,是因為我們指定了layoutkind.sequential,它的msdn的說明如下:

物件的成員按照它們在被匯出到非託管記憶體時出現的順序依次布局。這些成員根據在 system.runtime.interopservices.structlayoutattribute.pack中指定的封裝進行布局,並且可以是不連續的。

那麼,myojbect 的大小實際上就是所有資料成員記憶體位元組對齊後然後結構體的大小。

則vs2008上,位元組對齊(即structlayoutattribute.pack)預設設定好像是8。

下面是mydataobject物件在預設設定下的對齊情況:

成員 偏移位置(位元組) 記憶體分布(位元組)

a 0 0

x 4 4-7

b 8 8

c 16 16-23

總長度為24

現在我們來看位元組對齊為4的情況:

成員 偏移位置(位元組) 記憶體分布(位元組)

a 0 0

x 4 4-7

b 8 8

c 16 12-19

總長度為20。

位元組對齊為2的情況:

成員 偏移位置(位元組) 記憶體分布(位元組)

a 0 0

x 4 2-5

b 8 6

c 16 8-16

總長度為16。

位元組對齊為1的情況:這就是最緊湊的情況了。

成員 偏移位置(位元組) 記憶體分布(位元組)

a 0 0

x 4 1-4

b 8 5

c 16 6-13

總長度為14。

總體上來說,.net的物件占用的空間,跟其它非託管程式是一樣的,只是大部分的物件,由於是託管的,而且沒有規定記憶體布局,所以我們無法獲得其真正占用記憶體的大小。

ps:

structlayoutattribute類和marshal類位於命名空間「system.runtime.interopservices」下。

本來上面的對齊的排列順序,我寫的的時候中間有好幾個空格的,不知道為什麼發上來就成乙個空格了,排版不好看了,效應著看吧,呵呵

//------------我也來更新一下,不知道你們兩個人在爭什麼?

.net是中間語言,什麼叫做託管?託管的主要意思就是它把記憶體控制權接管了,簡之,你所寫的**並不是像c/c++那樣對記憶體的精確控制。

就拿c#來說,它是號稱沒有指標,但是,實際上大家都看得出來,它的所謂引用型引數,就是指標。為什麼這麼說?你試試呼叫乙個非託管的api,如果那個引數是指標型別的話,那你就得用ref了。

就拿你的問題classa a來說,現在我們就假定.net內部是指標,那麼

classa a,就相當於是定義了乙個指標,我們知道,指標在32位系統下,佔4位元組。當然,這裡還有乙個前提,就是classa是乙個class,不是struct或者其它值型別。

至於string型別的成員的占用記憶體的大小,不知道樓主你會不會c++,有沒有見過std的string是怎麼實現的?為了提交效率,降低記憶體分配頻率,string物件在建立時,就會預設了乙個容量長度,這個跟它儲存的字串長度是不一樣的,如果儲存的字串長度超過了容量,那麼它會再重新分配一塊更大的記憶體來儲存。但目前我還沒看到.net的string物件的源**,所以不知道它的預設容量是多大,那個就應該是它預設佔的記憶體大小。我只知道stringbuilder的預設容量是16,我想string的也許更大些吧。

末了,不知道你們討論乙個託管物件的占用記憶體大小還有什麼意義。

C 物件占多大記憶體?

前幾天被問到,在c 裡建立乙個空類什麼都成員沒有,它佔多大記憶體?我一下子懵掉了,還真沒想過這個問題。後來查了下資料終於明白了,且聽我慢慢道來。首先我們看一下這個測試程式 include using namespace std class test main static int x main cl...

Bitmap到底占多大記憶體

學習自 由xxhdpi這種資料夾控制,稱之為density1 由機型控制,稱之為density2 斜長 螢幕寸號 這兩者決定了一張圖在記憶體中轉化成的bitmap實際的width height xwidth width density1 density2 0.5 xheight height den...

大記憶體會變成雞肋,到底還要多大?

說起當下什麼是可以時刻伴隨著我們的東西,那麼手機絕對是當之無愧的。而說起手機不得不說的就是許多人在關注手機時非常關注的手機記憶體,從當初最開始的128kb,256kb在到最後智慧型手機出現為我們帶來的上gb的手機記憶體。再到現在的16gb,32gb.甚至是128gb或者256gb,這些都是手機記憶體...