何时准确加载装配件? [英] When exactly are assemblies loaded?

查看:88
本文介绍了何时准确加载装配件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

因此,我试图准确地了解何时将.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编译器有可能需要依赖程序集中的类型,它将导致程序集被加载? p>

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.

第一次调用方法 C 时,将加载Assembly3。

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天全站免登陆