如何判断.NET中的Class是大还是小?它是根据它的属性或字段的数量,其属性/字段的数据类型来衡量的吗?或返回类型的方法?它的方法的参数?访问其方法的修饰符,虚方法?感谢..
class A
{
string x { get; set; }
}
class B
{
int x { get; set; }
}
如果我像这样实例化A和B类,则在此示例中为
A objA = new A();
B objB = new B();
类objA是更大的一个,因为它包含一个String属性而objB只包含一个Int?虽然我没有为它的财产设定任何价值。感谢
编辑:只是为了澄清我的问题
假设我有一个班级
public class Member
{
public string MainEmpId { get; set; }
public string EmpId { get; set; }
}
和另一个班级
public class User
{
public string AccessLevel { get; set; }
public string DateActivated { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Mi { get; set; }
public string Password { get; set; }
public string UserId { get; set; }
public string UserName { get; set; }
public string Active { get; set; }
public string ProviderName { get; set; }
public string ContactPerson { get; set; }
public string Relation { get; set; }
public string Landline { get; set; }
public string MobileNo { get; set; }
public string Complaint { get; set; }
public string Remarks { get; set; }
public string Reason { get; set; }
public string RoomType { get; set; }
}
如果我像这样实例化
Member A = new Member();
User B = new User()
是对象A大于对象B吗? 我知道这是一个奇怪的问题,但我相信一个对象的每个实例都会占用内存空间..
答案 0 :(得分:40)
类实例的大小由以下各项确定:
因此,通常需要一个包含字符串属性的类(在32位系统上):
通常包含整数属性的类需要:
如您所见,字符串和整数属性在类中占用相同的空间,因此在您的第一个示例中,它们将使用相同的内存量。
string属性的值当然是另一回事,因为它可能指向堆上的字符串对象,但这是一个单独的对象,而不是指向它的类的一部分。
对于更复杂的类,填充起作用。例如,包含布尔值和字符串属性的类将使用:
请注意,这些是类的内存布局示例。确切的布局取决于框架的版本,CLR的实现,以及它是32位还是64位应用程序。由于程序可以在32位或64位系统上运行,编译器甚至不知道内存布局,因此在执行之前代码是JIT:ed时决定。
答案 1 :(得分:10)
通常,当一个类具有许多实例(非静态)字段时,它们的值越大,它就越大;类的最小内存为12个字节,引用类型的字段在32位系统上为4个字节,在64位系统上为8个字节。其他字段可以通过填充到字边界来布局,使得具有四个byte
字段的类实际上可以占用存储器中的四个4字节。但这一切都取决于运行时间。
不要忘记可能隐藏的字段,例如您的自动属性声明。由于它们在内部由字段支持,因此它们将增加类的大小:
public string MyProperty
{ get; set; }
请注意,以下属性对类大小没有影响,因为它没有字段支持:
public bool IsValid
{ get { return true; } }
要了解类或结构实例的内存大小:在类上应用[StructLayout(LayoutKind.Sequential)]
属性并在类型或实例上调用Marshal.SizeOf()
。
[StructLayout(LayoutKind.Sequential)]
public class MyClass
{
public int myField0;
public int myField1;
}
int sizeInBytes = Marshal.SizeOf(typeof(MyClass));
但是,因为运行时可以按照自己的意愿在内存中布局类,所以实例使用的实际内存可能会有所不同,除非您应用StructLayoutAttribute
。
答案 2 :(得分:2)
虽然以下文章是旧的(.NET 1.1),但这些概念清楚地解释了CLR正在为应用程序中实例化的对象分配内存的行为;他们放置了哪些堆,其对象引用指针正在寻址等等。
Drill Into .NET Framework Internals to See How the CLR Creates Runtime Objects
答案 3 :(得分:2)
您还可以查看:how-much-memory-instance-of-my-class-uses。 在调用构造函数之后,有一种简单的方法来测试对象的大小。
答案 4 :(得分:2)
github上的一个名为dotnetex的项目使用了一些魔法并显示了一个类或对象的大小。
用法很简单:
GCex.SizeOf<Object>(); // size of the type
GCEx.SizeOf(someObject); // size of the object;
引擎盖下它使用了一些魔法
要计算类型的大小,它会将方法表的指针强制转换为内部MethodTableInfo
结构,并使用它的Size
属性,如下所示:
public static unsafe Int32 SizeOf<T>()
{
return ((MethodTableInfo *)(typeof(T).TypeHandle.Value.ToPointer()))->Size;
}
要计算一个物体的大小,它会使用非常难以获得的真正的黑暗魔法:)看看the code。
答案 5 :(得分:0)
当一个人说班级大小时,我会认为这意味着班级有多少成员,以及班级有多复杂。
但是,您的问题是我们创建类实例时所需的内存大小。我们不能确定确切的大小,因为.Net框架保留并保持底层内存管理远离我们(这是一件好事)。即使我们现在拥有正确的尺寸,价值也可能永远正确。无论如何,我们可以确定以下内容将在内存中占用一些空间:
因此,有必要说User
类比Member
类占用的内存更多。