C#反射之使用绑定句柄减少进程的内存消耗

最近在看反射方面的东西的时候,看到最后发现一个与内存优化相关的东西,在此记录一下:

C#反射之使用绑定句柄减少进程的内存消耗

C#反射之使用绑定句柄减少进程的内存消耗

以下是文中介绍的 MethodInfo 和 RuntimeMethodHandle 相互转换测试代码:

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Diagnostics;
 4 using System.Reflection;
 5 
 6 namespace GenDLL
 7 {
 8     class Class1
 9     {
10         const BindingFlags bFlags = BindingFlags.FlattenHierarchy | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
11         public static void Main(string[] args)
12         {
13             //显示在任何反射操作之前的堆栈的大小
14             Show("Before doing anying");
15 
16             //为MSCorlib.dll中的所有方法构建 MethodInfo 对象缓存
17             List<MethodBase> methodInfoList = new List<MethodBase>();
18             //遍历定义  Object 类的程序集中定义的公共类型
19             foreach (Type type in typeof(Object).Assembly.GetExportedTypes())
20             {
21                 //过滤任何泛型的类型
22                 if (type.IsGenericTypeDefinition) continue;
23                 MethodBase[] array = type.GetMethods(bFlags);
24                 methodInfoList.AddRange(array);
25             }
26 
27             //显示当绑定所有方法之后,方法的个数和堆的大小
28             Console.WriteLine("# of method = {0:N0} ", methodInfoList.Count);
29             Show("After building cache of MethodInfo Object");
30 
31             //为所有的 MethodInfo 对象构建 RuntimeMethodHandle缓存
32             List<RuntimeMethodHandle> methodHandles = methodInfoList.ConvertAll<RuntimeMethodHandle>(mb => mb.MethodHandle);
33             Show("Holding MethodInfo and RuntimeMethodHandle of cache");
34             GC.KeepAlive(methodInfoList);   //阻止缓存被过早的回收
35             methodInfoList = null;          //现在允许进行回收
36             Show("After free MethodInfo Objects");
37 
38             methodInfoList = methodHandles.ConvertAll<MethodBase>(rmh => MethodBase.GetMethodFromHandle(rmh));                  //方式一
39             // methodInfoList = methodHandles.ConvertAll<MethodBase>(rmh => { return MethodBase.GetMethodFromHandle(rmh); });   //方式二
40             Show("Size of heap  After re-creating MethodInfo Objects");
41 
42             GC.KeepAlive(methodInfoList);   //阻止缓存被过早的回收
43             GC.KeepAlive(methodHandles);    //阻止缓存被过早的回收
44 
45             methodInfoList = null;
46             methodHandles = null;
47 
48             Show("After freeing  MethodInfos and RuntimeMethodHandles");
49 
50             Console.ReadLine();
51         }
52 
53         static void Show(string str)
54         {
55             //用逗号隔开的数字,0 表示占位符   12:N0 表示用逗号分隔数字,至少占12个字符,小数点后的位数为0
56             string format = "Heap Size = {0,12:N0} - {1}";
57             Console.WriteLine(format, GC.GetTotalMemory(true), str);
58         }
59     }
60 }

 

编程小知识之 GC.KeepAlive :https://blog.csdn.net/tkokof1/article/details/92073033

 

上一篇:C# 获取对象值,不获取地址


下一篇:EF查询出来的model,与自已创建的modl,取值进行更新