【问题标题】:Memory Allocation of Multicast delegate多播委托的内存分配
【发布时间】:2015-08-18 09:14:29
【问题描述】:

我正在阅读有关多播委托的内容,但内存分配的想法阻止了我。 有人可以解释多播委托的内存分配是如何完成的吗?(我故意不添加任何事件以使我更容易理解) 在这个程序中:

using System;

delegate int MyDelegate(int a,int b);
namespace DelegateAppl
{
    class DelegateTest
    {

        public static int AddNum(int p,int q)
        {
          int  add = p + q;
          return add;
        }

        public static int MultNum(int p, int q)
        {
            int mul = p * q;
            return mul;
        }


        static void Main(string[] args)
        {
            MyDelegate myDel = new MyDelegate(AddNum);
            myDel += new MyDelegate(MultNum);


            int result = myDel(2, 5);
           Console.WriteLine("Value of Num: {0}", result);

            Console.ReadKey();
        }
    }
}

Mydelegate 将如何分配。它的大小是 addNum 或 MultNum 还是两者相加?

MyThoughts-编译器会为 Mydelegate 分配一些内存(我不知道有多少)并将其存储在缓存中。然后它会根据方法(ADD)分配内存,然后删除和然后在通过委托调用时再次根据 Multiply 方法分配内存。 我的理解正确吗?

【问题讨论】:

  • 如果您有足够的委托人的总内存来构成您的应用程序的非零百分比,那么您做的事情非常非常错误。您不应该关心代表需要多少内存;它会全部归零。
  • 谢谢先生,我只是想知道多播代表的记忆是如何工作的。我无意更改或做任何可疑的事情。只是为了知识,在多播代表的情况下会发生什么,因为我们可以有一个引用两个方法的委托,一个打印字符串,另一个用 int 做一些事情。
  • 为什么要投反对票。我在发帖前搜索了很多,但可以得到任何答案。下次会提出更好的问题。如果它低于水平,请道歉
  • @Servy:这个问题不无道理。在某些情况下,算法的最简单实现会导致多订阅者事件频繁地附加和分离。使用Delegate.CombineDelegate.Remove 可能适用于很少有超过少数订阅者的事件,并且不适合有数万人的事件。但是,在何处划线可能会受到多播委托的存储方式以及所有 .NET 版本是否使用相同方法的影响。不难想象一个场景......
  • ...在一个 .NET 版本中操作 500 个订阅者事件可能会产生 100 倍于另一个版本的 GC 流失。我认为 .NET 事件处理从未以这种方式发生过变化,但不难想象它会这样做。

标签: c# delegates


【解决方案1】:

一个委托被编译成一个私有的密封类(包含类的),它对你是隐藏的——它是在编译时生成的。每次你初始化一个委托,比如MyDelegate myDel = new MyDelegate(AddNum);,你实际上是在初始化那个隐藏类的一个实例。该类还包含一个名为_invocationList 的字段,其类型为System.Object,用于引用另一个委托,并通过Delegate.Combine(Delegate that, Delegate other) 分配,这就是您编写myDel += new MyDelegate(MultNum); 时真正发生的情况。从中您可以弄清楚内存是如何分配的——它是常规对象的实例化。

【讨论】:

  • 谢谢先生,那么在使用匿名方法的多播声明的情况下,委托对象的大小将结合它所引用的所有方法的大小。假设委托 d 是否对 5 个方法(a,b, c,d,e),然后 5 refrence 将被添加到 _invocationList 中,这一切都变成了垃圾,因为我们没有为将来保存它们(它们只是匿名的)。我理解正确吗? _invocationList 中的引用大小是否固定?
  • _invocationList 就像链表的Next 字段,指向链中的下一个委托。匿名方法无论如何都会被编译为私有方法,所以它们不是特例。当您链接 5 个委托时,您只需创建一个包含 5 个节点的链表。
  • 谢谢,如果您可以提供有关此 Next 字段大小的任何大小信息?它是否等于它指向的方法的大小或某个固定值?
  • 我在答案中写道——它是 System.Object 类型,所以大小是一个参考。
  • 非常感谢您的建议并订购了:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-01-12
  • 1970-01-01
  • 2016-10-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多