什么时候加载程序集? [英] When exactly are assemblies loaded?

查看:23
本文介绍了什么时候加载程序集?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我试图准确地了解 .NET 程序集何时加载到 .NET 进程中.我读了 这篇博文 很好地解释了事情并证实了我认为我已经知道的很多东西,但它也提出了一个我认为我有点误解的观点.

So I'm trying to understand exactly when .NET Assemblies are loaded into a .NET process. I read this blog entry which did a great job of explaining things and confirmed a lot of what I thought I already knew, but it also brought up a point in which I think I slightly misunderstood.

依赖程序集在第一次引用时及时加载代码

Dependent Assemblies are just in time loaded when first referenced in code

我认为这意味着如果第一次调用程序集,然后该程序集被加载到程序中.因此,如果我有一个类似下面示例的程序,其中实例化 RasDialer 类的行永远不会被调用 - 我相信 DotRas 程序集永远不会被加载到这个过程,我绝对错了.

I took this to mean that when and furthermore if the first time a call to an assembly was made then the assembly was loaded into the program. So if I have a program like the sample below where the line in which the RasDialer class is instantiated would never be called - I believed that the DotRas assembly would never be loaded into the process and I was definitely wrong about that.

但是,如果代码真的像我注释掉的部分那样无法访问 - 那么程序集将永远不会加载,但似乎如果有机会,则程序集将被加载.

However, if the code is truly unreachable as in my commented out section - then the assembly will never load, but it seems that if there is a chance then the assembly will be loaded.

这是我的小测试应用程序:

static void Main(string[] args)
{
    Console.WriteLine("Before");
    var dictionary = new Dictionary<int, string>();
    PrintAssemblies(); // <- DotRas is loaded here for null check variant

    if (dictionary == null)
    {
        // This line will never execute, but it does not matter
        var dialer = new RasDialer();
    }

    // DotRas will not be loaded if I uncomment this and comment 
    // out the other if statement since it is truly unreachable
    //if (false)
    //{
    //    var dialer = new RasDialer();
    //}

    Console.WriteLine(Environment.NewLine + "After");
    PrintAssemblies();

    Console.ReadLine();
}

public static void PrintAssemblies()
{
    var assemblies = AppDomain.CurrentDomain.GetAssemblies();
    foreach (var assembly in assemblies)
    {
        Console.WriteLine(assembly.GetName());
    }
}

有什么简单的方法可以判断程序集何时加载到内存中?

Is there any easy way to tell when an assembly will be loaded into memory?

在我在顶部链接的博客条目中 - 他的依赖程序集直到他调用 PrintAssemblies() 之后才加载,但对于我的依赖程序集在调用之前加载.所以它似乎并不容易预测.

In the blog entry that I linked up at the top - his dependent assembly does not load until after his call to PrintAssemblies(), but for mine the dependent assembly loads before the call. So it doesn't appear to be easily predictable.

我是否正确地假设,如果 JIT 编译器需要依赖程序集中的类型,它会导致程序集被加载?

Am I correct to assume that if there is a chance that a type in the dependent assembly is needed by the JIT compiler it will cause the assembly to be loaded?

推荐答案

只要检查了引用程序集的方法,就会加载程序集.

The Assemblies are loaded as soon as a method that references your assembly get's checked.

大概就是从IL转换成机器码的时候.因此,只要您的方法引用另一个程序集中的代码,该程序集就会被加载.

Roughly that is, when converting from IL to machine code. So as soon as your method references code in another assembly that assembly is loaded.

因此,在您的示例中,包含 RasDialer 类的程序集将在第一次调用 Main 时加载,就在方法开始执行之前.

So in your example, the assembly that contains the RasDialer class, will be loaded on the first time Main is called, just before the executing of the method begins.

你应该知道一些小方法是内联的(但可能不是在调试时).因此,内联的代码将在内联后立即加载引用的程序集.

You should be aware that some small methods are inlined (but probably not while debugging). So code that is inlined, will load referenced assemblies as soon as it gets inlined.

  void A(object arg0) {
      if (argO == null) {
        ClassFromAssembly1.Call();
        B();
        C();
      }
  }

  void B() {
      ClassFromAssembly2.Call();
  }

  [MethodImpl(MethodImplOptions.NoInlining)]
  void C() {
      ClassFromAssembly3.Call();
  }

只要第一次调用方法 A,就在方法 A 的代码开始执行之前,Assembly1 和可能还有 Assembly2 都被加载.

As soon as method A is called for the first time, just before the code of method A starts executing, both Assembly1 and probably also Assembly2 are loaded.

Assembly3 将在第一次调用 C 方法时加载.

Assembly3 will be loaded, as soon as the first call to method C is made.

arg0 的值,不能用于控制Assembly1 的加载.何时加载 Assembly2,无法确定(取决于 B 的内联).可以通过arg0的值控制Assembly3的加载.

The value of arg0, cannot be used to control the loading of Assembly1. When Assembly2 will be loaded, cannot be determined (depends on the inlining of B). The loading of Assembly3 can be controlled with the value of arg0.

这篇关于什么时候加载程序集?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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