zoukankan      html  css  js  c++  java
  • .NET体系结构

    主要内容包括:

    C#与.NET的关系、公共语言运行库、中间语言、程序集、.NET Framework类、名称空间、内层管理...

    C#与.NET的关系

    C#是门高级编程语言,.NET(Framework)是个环境,用C#编写的所有代码总是在.NET Framework中运行。

    CLR公共语言运行库

     它是.NET Framework的核心,在CLR控制下运行的代码称为托管代码。CLR执行编写好的源代码之前,需要编译它。

    编译分两个阶段:

    1)将源代码编译为Microsoft中间语言(IL)

    2)CLR把IL编译为平台专用代码。

    这种设计的重要优点:

    1)平台无关性,依托的是:CTS是通用类型系统,CLS是通用语言规范,

    2)提高性能

    3)语言的互操作性,COM、windows运行库

    中间语言

    应用程序域

    就是为安全性,可靠性,隔离性,和版本控制,及卸载程序提供的隔离边界。它通常由运行库宿主创建,应用程序域提供了一个更安全,用途更广的处理单元。

    程序集

    程序集是.NET时代的动态链接库DLL,程序集是包含编译好的、面向.NET Framework的代码的逻辑单元。

    程序集包括(中间语言(IL),元数据(metaData),资源(resource),装配清单(AL))。

    它包含的元数据(描述自身的数据)描述了对应代码中定义的类型和方法。

    可以编程访问这些元数据,这个技术称为“反射”。抽象工厂设计模式中有用到:

    static string AssemblyName = Assembly.GetExecutingAssembly().GetName().Name; //获取程序集名称
    string className = AssemblyName+".Models" + "." + db + "User";   //命名空间.类名称
    (IUser)Assembly.Load(AssemblyName).CreateInstance(className);    //获取IUser程序集

    可执行代码和库代码,使用相同的程序集结构,他们的区别是:

    可执行代码的程序集包含一个主程序的入口点,而库程序集不包含。

    .NET Framework类

    属于托管类,使用托管代码的好处是可以使用.NET基类库,非常多的类的集合。大部分.net基类库是用C#写的。

    名称(命名)空间

    是.NET避免类名冲突的一种方式。

    Microsoft建议都至少要提供两个嵌套的命名空间名,第一个是公司名,第二个是技术名称或者软件包的名称,再之后是类名。

    内存管理

    1、GC(Garbage collector)

    GC是垃圾收集器。CLR通过GC实现的自动内存管理。

    1)什么被认为是可回收的对象?
    GC采用一定的算法遍历所有的对象,找出可达对象和不可达对象,不可达对象是可回收的对象。
    2)什么时候回收?
    通常情况下:内存不足溢出时,确切的说,是第一代对象已满的时候。
    3)如何回收?
    垃圾收集进程来释放不可达对象的内存空间。
    4)回收完后,还需要做什么?
    避免托管堆上的内存碎片,重新分配内存,压缩托管堆。
    5)避免垃圾回收带来的性能影响,采用代龄机制。

    如要请求垃圾收集,可以调用下面的方法之一: 
    System.gc()
    Runtime.getRuntime().gc()

    2、托管资源vs非托管资源

    资源就是程序中可利用的数据,譬如:字符串、图片和任何二进制数据,包括任何类型的文件。

    托管资源是由CLR全权负责的资源,CLR不负责的资源为非托管资源。
    对于托管资源通过GC自动清理回收。对于非托管资源,通过代码调用手动进行清除,再由GC回收
    如何正确的释放资源:对于非托管的资源,一般就是,Stream(流),数据库的连接,网络连接等的这些操作系统资源,需要我们手动去释放。

    Net提供了三种释放方法:Dispose,Close,析构函数(也就是Finalize方法)

    3、 托管内存与非托管内存之间的转换

    c#有自己的内存回收机制,所以在c#中我们可以只new,不用关心怎样delete,c#使用gc来清理内存,这部分内存就是managed memory,大部分时候我们工作于c#环境中,都是在使用托管内存,然而c#毕竟运行在c++之上,有的时候,(比如可能我们需要引入一些第三方的c++或native代码的库,在Unity3d开发中很常见)我们需要直接在c#中操纵非托管的代码,这些non-managed memory我们就需要自己去处理他们的申请和释放了, c# 中提供了一些接口,完成托管和非托管之间的转换,以及对这部分内存的操作。

    主要通过Marshal类和GCHandle类,编程时只要注意非托管的内存一定要负责好释放就可以了。

    例如:Marshal.AllocHGlobal()

    public static IntPtr AllocHGlobal(
        int cb  //内存中的所需字节数。
    )
    通过使用指定的字节数,从进程的非托管内存中分配内存。
    返回值:指向新分配的内存的指针。 必须使用释放此内存 Marshal.FreeHGlobal 方法。
    public static void FreeHGlobal(
        IntPtr hglobal
    )
    IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(cardCfg));
    Marshal.StructureToPtr(cardCfg, ptr, false);
    
    InrPtr是个结构体:用于表示指针或句柄的平台特定类型。
    FreeHGlobal()用法
    //byte[]转换为Intptr
      public static Intptr BytesToIntptr(byte[] bytes)
      {
        int size = bytes.Length;
        IntPtr buffer = Marshal.AllocHGlobal(size);
        try
          {
           Marshal.Copy(bytes, 0, buffer, size);
           return buffer;
          }
        finally
          {
           Marshal.FreeHGlobal(buffer); //释放以前从进程的非托管内存中分配的内存。
          }
      }
    View Code
  • 相关阅读:
    HDU 5828 Rikka with Sequence (线段树+剪枝优化)
    Educational Codeforces Round 5 E. Sum of Remainders (思维题)
    HDU 2256 Problem of Precision (矩阵快速幂)
    Codeforces 597C. Subsequences (树状数组+dp)
    Codeforces Round #292 (Div. 1) B. Drazil and Tiles (类似拓扑)
    HDU 5794 A Simple Chess (Lucas + dp)
    Codeforces Round #365 (Div. 2) D. Mishka and Interesting sum (离线树状数组+前缀xor)
    Codeforces Round #313 (Div. 2) E. Gerald and Giant Chess (Lucas + dp)
    进程内存空间的分布
    快排,堆排与归并排序
  • 原文地址:https://www.cnblogs.com/peterYong/p/6556749.html
Copyright © 2011-2022 走看看