事件和事件订阅的数据大小是多少?
本文关键字:事件 多少 数据 | 更新日期: 2023-09-27 18:06:59
很抱歉没有时间在活动上尝试sizeof但是本着增强google-fu的精神....
-
有事件字段的类实例实际内存大小是多少?
-
每次订阅一个事件将使用多少实际内存?
我假设每个事件或订阅都有一个指针,但我只是想确定。
考虑这个例子:
public class VertexMovedArgs : EventArgs {
public Vertex theVert;
}
public class Vertex {
// what size does this add to each Vertex?
public event EventHandler<VertexMovedArgs> VertexMovedEvent;
private Vector3 m_pos;
public Vector3 pos {
get { return m_pos; }
set {
if ( value != m_pos ) {
m_pos = value;
EventHandler<VertexMovedArgs> tellEveryoneWeMoved = VertexMovedEvent;
if ( handler != null ) {
VertexMovedArgs args = new VertexMovedArgs( this );
tellEveryoneWeMoved( this, args );
}
}
}
}
}
public class Mesh {
private List<Vertex> m_verts = new List<Vertex>();
public Vertex AddVert() {
Vertex vert = new Vertex();
// what size per-subscription does this add to this Mesh instance (or elsewhere)?
vert.VertexMovedEvent += onVertexMoved;
m_verts.Add( vert );
}
void onVertexMoved( object sender, VertexMovedArgs args ) {
// play the vertex like a violin, etc...
}
}
事件字段只是一个对象引用。
在你将处理程序(委托)放入其中之前,每个类实例只消耗一个指针大小(4或8字节)。
委托实例有四个指针大小的字段,加上标准的CLR对象头。
他们商店:
- 调用封闭委托的目标 指向的函数的MethodBase
- 调用 的函数指针
- 存储实际指向的函数的地址的辅助指针(与打开委托一起使用以重新排列参数)
多播委托(在实践中,所有普通委托)增加两个:
- 组播委托指向的委托数组(单个委托为
null
) -
_invocationCount
(和IntPtr
),用于不同类型的委托
我正在写一篇博客,将更详细地解释这些字段。
事件是一对方法,用于添加和删除订阅(实际上,它是三个方法,但第三个方法通常不用于任何事情)。事件本身不会增加对象实例的大小,但添加/删除逻辑通常必须添加至少一个字段。事件最常见的默认实现是创建一个MultiCastDelegate类型的字段,并使用Delegate。组合可添加订阅和委托。