Maison >développement back-end >Tutoriel C#.Net >C# utilise des handles de liaison pour réduire la consommation de mémoire du processus
Dans de nombreuses applications, un ensemble de types (Type) ou de membres de type (dérivés de MemberInfo) sont liés et ces objets sont stockés dans une certaine forme de collection. Plus tard, cette collection est recherchée pour un objet spécifique puis appelée. C'est un mécanisme sympa, mais il y a un petit problème : les objets dérivés de Type et MemberInfo nécessitent beaucoup de mémoire. Si une application contient trop de classes de ce type mais ne les utilise qu'occasionnellement, la mémoire de l'application augmentera rapidement, affectant ses performances.
En interne, le CLR représente ces informations sous une forme plus condensée. Le CLR crée ces objets pour les applications simplement pour faciliter la vie du développeur. Le CLR n'a pas besoin de ces objets volumineux au moment de l'exécution. Si un grand nombre d’objets dérivés Type et MemberInfo doivent être mis en cache, les développeurs peuvent utiliser des descripteurs d’exécution au lieu d’objets pour réduire l’espace de travail (mémoire occupée). FCL définit trois types de handles d'exécution (tous dans l'espace de noms System), RuntimeTypeHandle, RuntimeFieldHandle et RumtimeMethodHandle. Les trois types sont des types valeur et ils ne contiennent qu'un seul champ, qui est un IntPtr ; les instances de ces types économisent donc beaucoup de mémoire. Le champ ItPtr est un handle qui fait référence à un type, un champ ou une méthode dans le tas Loader d’AppDomain. Méthode de conversion :
Type→RuntimeTypeHandle, en interrogeant l'attribut de champ en lecture seule TypeHandle de Type.
RuntimeTypeHandle→Type, en appelant la méthode statique GetTypeFromHanlde de Type.
FieldInfo→RuntimeFieldHandle, en interrogeant le champ en lecture seule de l'instance FieldHandle de FieldInfo.
RuntimeFieldHandle→FieldInfo, en appelant la méthode statique GetFieldFromHandle de FieldInfo.
MethodInfo→RuntimeMethodHandle, en interrogeant le champ en lecture seule de l'instance MethodHandle de MethodInof.
RuntimeMethodHandle→MethodInfo, en appelant la méthode statique GetMethodFromHandle de MethodInfo.
L'exemple suivant obtient de nombreux objets MethodInfo, les convertit en instances RuntimeMethodHandle et démontre la différence de mémoire avant et après la conversion.
private void UseRuntimeHandleToReduceMemory() { Show("Before doing anything");//从MSCorlib.dll中地所有方法构建methodInfos 对象缓存 List<MethodBase> methodInfos = new List<MethodBase>(); foreach (Type t in typeof(object).Assembly.GetExportedTypes()) { if (t.IsGenericType) continue; MethodBase[] mbs = t.GetMethods(c_bf); methodInfos.AddRange(mbs); } //显示当绑定所有方法之后,方法的个数和堆的大小 Console.WriteLine("# of Methods={0:###,###}", methodInfos.Count); Show("After building cache of MethodInfo objects");//为所有MethodInfo对象构建RuntimeMethodHandle缓存 List<RuntimeMethodHandle> methodHandles = new List<RuntimeMethodHandle>(); methodHandles = methodInfos.ConvertAll<RuntimeMethodHandle>(m => m.MethodHandle); Show("Holding MethodInfo and RuntimeMethodHandle"); GC.KeepAlive(methodHandles);//阻止缓存被过早垃圾回收 methodInfos = null;//现在允许缓存垃圾回收 Show("After freeing MethodInfo objects"); methodInfos = methodHandles.ConvertAll<MethodBase>(r => MethodBase.GetMethodFromHandle(r)); Show("Size of heap after re-creating methodinfo objects"); GC.KeepAlive(methodHandles);//阻止缓存被过早垃圾回收 GC.KeepAlive(methodInfos);//阻止缓存被过早垃圾回收 methodInfos = null;//现在允许缓存垃圾回收 methodHandles = null;//现在允许缓存垃圾回收 Show("after freeing MethodInfo and MethodHandle objects"); }
Les résultats sont les suivants :
Heap Size = 114,788 - Before doing anything # of Methods=10,003Heap Size = 2,205,652 - After building cache of MethodInfo objects Heap Size = 2,245,744 - Holding MethodInfo and RuntimeMethodHandle Heap Size = 2,171,976 - After freeing MethodInfo objects Heap Size = 2,327,516 - Size of heap after re-creating methodinfo objects Heap Size = 247,028 - after freeing MethodInfo and MethodHandle objects
Cet article est compilé à partir de "NET CLR via C#"
Auteur : jiankunking Source : http ://www.php.cn/
Dans de nombreuses applications, un ensemble de types (Type) ou de membres de type (dérivés de MemberInfo) sont liés et ces objets sont stockés sous une certaine forme de collection. . Plus tard, cette collection est recherchée pour un objet spécifique, puis appelée sur cet objet. C'est un mécanisme sympa, mais il y a un petit problème : les objets dérivés de Type et MemberInfo nécessitent beaucoup de mémoire. Si une application contient trop de classes de ce type mais ne les utilise qu'occasionnellement, la mémoire de l'application augmentera rapidement, affectant ses performances.
En interne, le CLR représente ces informations sous une forme plus condensée. Le CLR crée ces objets pour les applications simplement pour faciliter la vie du développeur. Le CLR n'a pas besoin de ces objets volumineux au moment de l'exécution. Si un grand nombre d’objets dérivés Type et MemberInfo doivent être mis en cache, les développeurs peuvent utiliser des descripteurs d’exécution au lieu d’objets pour réduire l’espace de travail (mémoire occupée). FCL définit trois types de handles d'exécution (tous dans l'espace de noms System), RuntimeTypeHandle, RuntimeFieldHandle et RumtimeMethodHandle. Les trois types sont des types valeur et ils ne contiennent qu'un seul champ, qui est un IntPtr ; les instances de ces types économisent donc beaucoup de mémoire. Le champ ItPtr est un handle qui fait référence à un type, un champ ou une méthode dans le tas Loader d’AppDomain. Méthode de conversion :
Type→RuntimeTypeHandle, en interrogeant l'attribut de champ en lecture seule TypeHandle de Type.
RuntimeTypeHandle→Type, en appelant la méthode statique GetTypeFromHanlde de Type.
FieldInfo→RuntimeFieldHandle, en interrogeant le champ en lecture seule de l'instance FieldHandle de FieldInfo.
RuntimeFieldHandle→FieldInfo, en appelant la méthode statique GetFieldFromHandle de FieldInfo.
MethodInfo→RuntimeMethodHandle, en interrogeant le champ en lecture seule de l'instance MethodHandle de MethodInof.
RuntimeMethodHandle→MethodInfo, en appelant la méthode statique GetMethodFromHandle de MethodInfo.
L'exemple suivant obtient de nombreux objets MethodInfo, les convertit en instances RuntimeMethodHandle et démontre la différence de mémoire avant et après la conversion.
private void UseRuntimeHandleToReduceMemory() { Show("Before doing anything");//从MSCorlib.dll中地所有方法构建methodInfos 对象缓存 List<MethodBase> methodInfos = new List<MethodBase>(); foreach (Type t in typeof(object).Assembly.GetExportedTypes()) { if (t.IsGenericType) continue; MethodBase[] mbs = t.GetMethods(c_bf); methodInfos.AddRange(mbs); } //显示当绑定所有方法之后,方法的个数和堆的大小 Console.WriteLine("# of Methods={0:###,###}", methodInfos.Count); Show("After building cache of MethodInfo objects");//为所有MethodInfo对象构建RuntimeMethodHandle缓存 List<RuntimeMethodHandle> methodHandles = new List<RuntimeMethodHandle>(); methodHandles = methodInfos.ConvertAll<RuntimeMethodHandle>(m => m.MethodHandle); Show("Holding MethodInfo and RuntimeMethodHandle"); GC.KeepAlive(methodHandles);//阻止缓存被过早垃圾回收 methodInfos = null;//现在允许缓存垃圾回收 Show("After freeing MethodInfo objects"); methodInfos = methodHandles.ConvertAll<MethodBase>(r => MethodBase.GetMethodFromHandle(r)); Show("Size of heap after re-creating methodinfo objects"); GC.KeepAlive(methodHandles);//阻止缓存被过早垃圾回收 GC.KeepAlive(methodInfos);//阻止缓存被过早垃圾回收 methodInfos = null;//现在允许缓存垃圾回收 methodHandles = null;//现在允许缓存垃圾回收 Show("after freeing MethodInfo and MethodHandle objects"); }
Les résultats sont les suivants :
Heap Size = 114,788 - Before doing anything # of Methods=10,003Heap Size = 2,205,652 - After building cache of MethodInfo objects Heap Size = 2,245,744 - Holding MethodInfo and RuntimeMethodHandle Heap Size = 2,171,976 - After freeing MethodInfo objects Heap Size = 2,327,516 - Size of heap after re-creating methodinfo objects Heap Size = 247,028 - after freeing MethodInfo and MethodHandle objects
Ce qui précède est le contenu de C# utilisant des poignées de liaison pour réduire la consommation de mémoire du processus. Pour plus de contenu connexe, veuillez payer. attention au site PHP chinois (www.php.cn) !