C#中继承的内存布局 [英] Memory layout of inheritance in C#

查看:270
本文介绍了C#中继承的内存布局的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果创建派生类对象,在堆上分配的内存是什么?

内存是分配给派生类还是包含基类内存?

如果是,那么如果我连续导出10次怎么办?

这是否会影响程序的性能?

我的意思是如果我调用最后一个派生类,应该创建10个类的内存。这不是性能上的开销吗?请解释确切的内存分配模式



我尝试过:



这是一个概念性问题。因此我找不到任何方法来实现任何策略

解决方案

没有完全准确的方法来确定实例化的对象大小,但此示例中显示的此代码应该让你非常接近:



  private   static   long  GetObjectSize( object  obj)
{
long size = 0 ;
使用(Stream s = new MemoryStream())
{
BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(s,obj);
size = s.Length;
}
返回大小;
}





我创建了一个带有两个字符串属性的简单类,然后是另一个派生自第一个没有任何字符串的类其他属性/代码/字段。



非衍生版本(上面的代码)显示202个字节。



派生版本显示225个字节。



还有一些额外的内存消耗(这是预期的),但我还是留给你确定如果增加的内存消耗是线性的或几何的,具有更复杂的基类。



最后,它实际上是无关紧要的。您不应该以牺牲可维护性为代价来编写(假/假想?)内存优化。



如果你对.Net中的内存分配感兴趣,只要谷歌阅读并阅读,只要你能保持对该主题的兴趣。



我忘记提到我提供的代码只有在相关课程中应用 [Serializable] 属性时才有效。 br />


编辑==================================



经过一些粗略的测试,似乎对象名称的长度(以及它们的属性和方法的名称)是多少额外内存的决定因素被分配给派生类。此外,尽管如此,继承类消耗的额外内存量(给定我非常简单的类)似乎是一个相当静态的百分比(大约11%)。


不,有只有最终派生类的一个实例。



没有中间派生类链接在一起。



将子类(在某些方面)视为相关的,更原始的类的逻辑剪切和粘贴功能。


< blockquote>您可能会想到基类,以及从基类继承的类,直接,或者从基类作为其根祖先的类下降 ...



作为生产线:每次创建类的实例时:生产线的不同部分被称为动作以生成实例。



实例的内存消耗是w的结果在祖先的类链中的每个级别都声明了帽子字段,方法,属性等。



我认为学习OOP以保持专注是有价值的关于声明结构之间的区别...创建类,接口,结构......并将该结构实例化为可用的运行对象。



类是蓝色 - 房屋:实例化是建房的过程;房屋成本是多少是材料和劳动力成本的函数。


what would be the memory allocated on heap if the derived class object is created?
Is the memory allocated to derived class or it includes memory for base class too?
If yes, then what if I consecutively derive 10 times?
Doesn't this affect performance of program?
I mean memory of 10 classes should be created if I call last derived class. Isn't this a overhead on performance? please explain the exact memory allocation pattern

What I have tried:

this is a conceptual question. thus I couldn't find any way for implementing any of strategy

解决方案

There is no completely accurate way to determine instantiated object size, but this code shown in this example should get you pretty close:

private static long GetObjectSize(object obj)
{
    long size = 0;
    using (Stream s = new MemoryStream()) 
    {
        BinaryFormatter formatter = new BinaryFormatter();
        formatter.Serialize(s, obj);
        size = s.Length;
    }
    return size;
}



I created a simple class with two string properties, and then another class that derives from the first one without any additional properties/code/fields.

The non-derived version (with the code above) showed 202 bytes.

The derived version showed 225 bytes.

There is some additional memory consumption (and that's to be expected), but I leave it up to you to determine if the increased memory consumption is linear or geometric with more complex base classes.

In the end, it really is irrelevant. You shouldn't code for (false/imagined?) memory optimization at the expense of maintainability.

If you're interested in memory allocation in .Net, just google it and read for as long as you can maintain interest in the subject.

I forgot to mention that the code I provided will only work if the classes in question have the [Serializable] attribute applied.

EDIT ==================================

After some cursory testing, it appears as if the length of the object names (and the names of their properties and methods) is a determining factor in how much additional memory is allocated to a derived class. Also, despite that, the amount of additional memory consumed by an inheriting class (given my very simple classes) appears to be a reasonably static percentage (around 11%).


No, there is only "one" instance of the "final" derived class.

There are no "intermediate" derived classes "chained" together.

Think of "sub-classing" (in some ways) as a "logical" cut-and-paste of functionality from a related, more primitive, class.


You might think of the base class, and the classes that descend from the base class, either directly, or descend from a class that has the base class as its root ancestor ...

as being a production line: each time you create an instance of a class: the different parts of the production line are called into "action" to produce the instance.

The memory consumption of an instance is an outcome of what fields, methods, properties, etc., were declared at each "level" in the class chain of ancestors.

I think it's valuable in learning OOP to keep focused on the difference between declaring structure ... creating classes, interfaces, structs ... and instantiating that structure into usable run-tine objects.

The Class is a blue-print for a "house:" instantiation is the process of building the house; how much the house "cost" is a function of the cost of its materials and labor.


这篇关于C#中继承的内存布局的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆