最近在看反射方面的东西的时候,看到最后发现一个与内存优化相关的东西,在此记录一下:
以下是文中介绍的 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