C# verwendet Bind-Handles, um den Prozessspeicherverbrauch zu reduzieren

黄舟
Freigeben: 2017-02-13 11:32:49
Original
1885 Leute haben es durchsucht


In vielen Anwendungen ist eine Reihe von Typen (Type) oder Typmitglieder (abgeleitet von MemberInfo) gebunden und diese Objekte werden in einer Art Sammlung gespeichert. Später wird diese Sammlung nach einem bestimmten Objekt durchsucht und dann aufgerufen. Dies ist ein netter Mechanismus, aber es gibt ein kleines Problem: Von Type und MemberInfo abgeleitete Objekte benötigen viel Speicher. Wenn eine Anwendung zu viele solcher Klassen enthält, diese aber nur gelegentlich verwendet, wächst der Speicher der Anwendung schnell, was sich auf die Leistung der Anwendung auswirkt.

Intern stellt die CLR diese Informationen in einer komprimierteren Form dar. Die CLR erstellt diese Objekte für Anwendungen, um dem Entwickler das Leben zu erleichtern. Die CLR benötigt diese großen Objekte zur Laufzeit nicht. Wenn eine große Anzahl abgeleiteter Type- und MemberInfo-Objekte zwischengespeichert werden muss, können Entwickler Laufzeithandles anstelle von Objekten verwenden, um den Arbeitssatz (belegten Speicher) zu reduzieren. FCL definiert drei Laufzeit-Handle-Typen (alle im System-Namespace): RuntimeTypeHandle, RuntimeFieldHandle und RumtimeMethodHandle. Alle drei Typen sind Werttypen und enthalten nur ein Feld, nämlich ein IntPtr. Daher sind Instanzen dieser Typen ziemlich speichersparend. Das ItPtr-Feld ist ein Handle, das auf einen Typ, ein Feld oder eine Methode im Loader-Heap der AppDomain verweist. Konvertierungsmethode:

  • Type→RuntimeTypeHandle, durch Abfrage des schreibgeschützten Feldattributs TypeHandle von Type.

  • RuntimeTypeHandle→Type, durch Aufrufen der statischen Methode GetTypeFromHanlde von Type.

  • FieldInfo→RuntimeFieldHandle, durch Abfrage des schreibgeschützten Instanzfelds FieldHandle von FieldInfo.

  • RuntimeFieldHandle→FieldInfo, durch Aufrufen der statischen Methode GetFieldFromHandle von FieldInfo.

  • MethodInfo→RuntimeMethodHandle, durch Abfrage des schreibgeschützten Instanzfelds MethodHandle von MethodInof.

  • RuntimeMethodHandle→MethodInfo, durch Aufrufen der statischen Methode GetMethodFromHandle von MethodInfo.

Das folgende Beispiel ruft viele MethodInfo-Objekte ab, konvertiert sie in RuntimeMethodHandle-Instanzen und demonstriert den Speicherunterschied vor und nach der Konvertierung.

 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");
        }
Nach dem Login kopieren
Nach dem Login kopieren

Die Ergebnisse sind wie folgt:

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
Nach dem Login kopieren
Nach dem Login kopieren

Dieser Artikel wurde aus „NET CLR via C#“ zusammengestellt

Autor: jiankunking Quelle: http ://www.php.cn/

In vielen Anwendungen ist eine Reihe von Typen (Type) oder Typmitglieder (abgeleitet von MemberInfo) gebunden und diese Objekte werden in einer Art Sammlung gespeichert . Später wird diese Sammlung nach einem bestimmten Objekt durchsucht und dann aufgerufen. Dies ist ein netter Mechanismus, aber es gibt ein kleines Problem: Von Type und MemberInfo abgeleitete Objekte benötigen viel Speicher. Wenn eine Anwendung zu viele solcher Klassen enthält, diese aber nur gelegentlich verwendet, wächst der Speicher der Anwendung schnell, was sich auf die Leistung der Anwendung auswirkt.

Intern stellt die CLR diese Informationen in einer komprimierteren Form dar. Die CLR erstellt diese Objekte für Anwendungen, um dem Entwickler das Leben zu erleichtern. Die CLR benötigt diese großen Objekte zur Laufzeit nicht. Wenn eine große Anzahl abgeleiteter Type- und MemberInfo-Objekte zwischengespeichert werden muss, können Entwickler Laufzeithandles anstelle von Objekten verwenden, um den Arbeitssatz (belegten Speicher) zu reduzieren. FCL definiert drei Laufzeit-Handle-Typen (alle im System-Namespace): RuntimeTypeHandle, RuntimeFieldHandle und RumtimeMethodHandle. Alle drei Typen sind Werttypen und enthalten nur ein Feld, nämlich ein IntPtr. Daher sind Instanzen dieser Typen ziemlich speichersparend. Das ItPtr-Feld ist ein Handle, das auf einen Typ, ein Feld oder eine Methode im Loader-Heap der AppDomain verweist. Konvertierungsmethode:

  • Type→RuntimeTypeHandle, durch Abfrage des schreibgeschützten Feldattributs TypeHandle von Type.

  • RuntimeTypeHandle→Type, durch Aufrufen der statischen Methode GetTypeFromHanlde von Type.

  • FieldInfo→RuntimeFieldHandle, durch Abfrage des schreibgeschützten Instanzfelds FieldHandle von FieldInfo.

  • RuntimeFieldHandle→FieldInfo, durch Aufrufen der statischen Methode GetFieldFromHandle von FieldInfo.

  • MethodInfo→RuntimeMethodHandle, durch Abfrage des schreibgeschützten Instanzfelds MethodHandle von MethodInof.

  • RuntimeMethodHandle→MethodInfo, durch Aufrufen der statischen Methode GetMethodFromHandle von MethodInfo.

Das folgende Beispiel ruft viele MethodInfo-Objekte ab, konvertiert sie in RuntimeMethodHandle-Instanzen und demonstriert den Speicherunterschied vor und nach der Konvertierung.

 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");
        }
Nach dem Login kopieren
Nach dem Login kopieren

Die Ergebnisse sind wie folgt:

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
Nach dem Login kopieren
Nach dem Login kopieren

Das Obige ist der Inhalt von C#, der Bindungshandles verwendet, um den Speicherverbrauch des Prozesses zu reduzieren. Für weitere verwandte Inhalte zahlen Sie bitte Achtung auf die chinesische PHP-Website (www.php.cn)!


Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage
Über uns Haftungsausschluss Sitemap
Chinesische PHP-Website:Online-PHP-Schulung für das Gemeinwohl,Helfen Sie PHP-Lernenden, sich schnell weiterzuentwickeln!