C# 使用绑定句柄来减少进程的内存耗用
许多应用程序中,绑定了一组类型(Type)或者类型成员(从MemberInfo派生),并将这些对象保存在某种形式的一个集合中。以后,会搜索这个集合,查找特定的对象,然后调用这个对象。这是一个很好的机制,但是有个小问题:Type和MemberInfo派生的对象需要大量的内存。如果一个应用程序容纳了太多这样的类,但只是偶尔用一下它们,应用程序的内存就会急剧增长,对应用程序的性能产生影响。
在内部,CLR用一种更精简的形式来表示这种信息。CLR之所以为应用程序创建这些对象,只是为了简化开发人员的工作。CLR在运行时并不需要这些大对象。如果需要缓存大量Type和MemberInfo派生对象,开发人员可以使用运行时句柄(runtime handle)来代替对象,从而减少工作集(占用的内存)。FCL定义了3个运行时句柄类型(都在System命名空间中),RuntimeTypeHandle,RuntimeFieldHandle,RumtimeMethodHandle。三个类型都是值类型,他们只包含了一个字段,也就是一个IntPtr;这样一来,这些类型的实例就相当省内存。ItPtr字段是一个句柄,它引用了AppDomain的Loader堆中的一个类型,字段或方法。转换方法:
Type→RuntimeTypeHandle,通过查询Type的只读字段属性TypeHandle。
RuntimeTypeHandle→Type,通过调用Type的静态方法GetTypeFromHanlde。
FieldInfo→RuntimeFieldHandle,通过查询FieldInfo的实例只读字段FieldHandle。
RuntimeFieldHandle→FieldInfo,通过调用FieldInfo的静态方法GetFieldFromHandle。
MethodInfo→RuntimeMethodHandle,通过查询MethodInof的实例只读字段MethodHandle。
RuntimeMethodHandle→MethodInfo,通过调用MethodInfo的静态方法GetMethodFromHandle。
下面的示例获取许多的MethodInfo对象,把它们转化成RuntimeMethodHandle实例,并演示转换前后的内存差异。
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"); }
结果如下:
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
本文整理自《NET CLR via C#》
作者:jiankunking 出处:http://www.php.cn/
许多应用程序中,绑定了一组类型(Type)或者类型成员(从MemberInfo派生),并将这些对象保存在某种形式的一个集合中。以后,会搜索这个集合,查找特定的对象,然后调用这个对象。这是一个很好的机制,但是有个小问题:Type和MemberInfo派生的对象需要大量的内存。如果一个应用程序容纳了太多这样的类,但只是偶尔用一下它们,应用程序的内存就会急剧增长,对应用程序的性能产生影响。
在内部,CLR用一种更精简的形式来表示这种信息。CLR之所以为应用程序创建这些对象,只是为了简化开发人员的工作。CLR在运行时并不需要这些大对象。如果需要缓存大量Type和MemberInfo派生对象,开发人员可以使用运行时句柄(runtime handle)来代替对象,从而减少工作集(占用的内存)。FCL定义了3个运行时句柄类型(都在System命名空间中),RuntimeTypeHandle,RuntimeFieldHandle,RumtimeMethodHandle。三个类型都是值类型,他们只包含了一个字段,也就是一个IntPtr;这样一来,这些类型的实例就相当省内存。ItPtr字段是一个句柄,它引用了AppDomain的Loader堆中的一个类型,字段或方法。转换方法:
Type→RuntimeTypeHandle,通过查询Type的只读字段属性TypeHandle。
RuntimeTypeHandle→Type,通过调用Type的静态方法GetTypeFromHanlde。
FieldInfo→RuntimeFieldHandle,通过查询FieldInfo的实例只读字段FieldHandle。
RuntimeFieldHandle→FieldInfo,通过调用FieldInfo的静态方法GetFieldFromHandle。
MethodInfo→RuntimeMethodHandle,通过查询MethodInof的实例只读字段MethodHandle。
RuntimeMethodHandle→MethodInfo,通过调用MethodInfo的静态方法GetMethodFromHandle。
下面的示例获取许多的MethodInfo对象,把它们转化成RuntimeMethodHandle实例,并演示转换前后的内存差异。
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"); }
结果如下:
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
以上就是C# 使用绑定句柄来减少进程的内存耗用的内容,更多相关内容请关注PHP中文网(www.php.cn)!

Alat AI Hot

Undresser.AI Undress
Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover
Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool
Gambar buka pakaian secara percuma

Clothoff.io
Penyingkiran pakaian AI

AI Hentai Generator
Menjana ai hentai secara percuma.

Artikel Panas

Alat panas

Notepad++7.3.1
Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina
Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1
Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6
Alat pembangunan web visual

SublimeText3 versi Mac
Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Topik panas

Panduan untuk Active Directory dengan C#. Di sini kita membincangkan pengenalan dan cara Active Directory berfungsi dalam C# bersama-sama dengan sintaks dan contoh.

Panduan kepada Pengubahsuai Akses dalam C#. Kami telah membincangkan Pengenalan Jenis Pengubahsuai Akses dalam C# bersama-sama dengan contoh dan output.

Panduan untuk Penjana Nombor Rawak dalam C#. Di sini kita membincangkan cara Penjana Nombor Rawak berfungsi, konsep nombor pseudo-rawak dan selamat.

Panduan untuk Paparan Grid Data C#. Di sini kita membincangkan contoh cara paparan grid data boleh dimuatkan dan dieksport daripada pangkalan data SQL atau fail excel.

Panduan kepada Corak dalam C#. Di sini kita membincangkan pengenalan dan 3 jenis Corak teratas dalam C# bersama-sama dengan contoh dan pelaksanaan kodnya.

Panduan untuk Pensirian C#. Di sini kita membincangkan pengenalan, langkah-langkah objek siri C#, kerja, dan contoh masing-masing.

Panduan untuk Perkhidmatan Web dalam C#. Di sini kita membincangkan pengenalan kepada Perkhidmatan Web dalam C# dengan penggunaan teknologi, had dan contoh.

Panduan Nombor Perdana dalam C#. Di sini kita membincangkan pengenalan dan contoh nombor perdana dalam c# bersama dengan pelaksanaan kod.
