(Это все из Microsoft Shared Source CLI ; он имеет исходный код CLR.)
Если вы посмотрите на clr\src\vm\object.h
, вы увидите:
// The generational GC requires that every object be at least 12 bytes in size.
#define MIN_OBJECT_SIZE (2*sizeof(BYTE*) + sizeof(ObjHeader))
, что довольно очевидно. Кроме того, в clr\src\vm\gcscan.cpp
вы можете увидеть такие утверждения, как
_ASSERTE(g_pObjectClass->GetBaseSize() == MIN_OBJECT_SIZE);
или
_ASSERTE(totalSize < totalSize + MIN_OBJECT_SIZE);
, который, я думаю, объясняет, почему вы видите неожиданные размеры объектов. :)
Обновление:
@ Ганс отлично показал себя в блоке синхронизации; Я просто хочу указать на тонкость, задокументированную снова в object.h
:
/* Object
*
* This is the underlying base on which objects are built. The MethodTable
* pointer and the sync block index live here. The sync block index is actually
* at a negative offset to the instance. See syncblk.h for details.
*/
class Object
{
protected:
MethodTable* m_pMethTab;
//No other fields shown here!
};
Обратите внимание на эту часть:
Индекс блока синхронизации фактически имеет отрицательное смещение к экземпляру.
Таким образом, блок синхронизации, по-видимому, на самом деле не следует таблице методов (как упоминал Ханс), но он приходит до этого - так что это не «нормальная» часть объект (из-за отсутствия лучшего слова).