>  기사  >  백엔드 개발  >  C#에서는 바인드 핸들을 사용하여 프로세스 메모리 소비를 줄입니다.

C#에서는 바인드 핸들을 사용하여 프로세스 메모리 소비를 줄입니다.

黄舟
黄舟원래의
2017-02-13 11:32:491887검색


많은 애플리케이션에서 유형 집합(Type) 또는 유형 멤버(MemberInfo에서 파생됨)가 바인딩되고 이러한 개체는 컬렉션 형식으로 저장됩니다. 나중에 이 컬렉션에서 특정 개체를 검색한 다음 해당 개체에 대해 호출합니다. 이는 좋은 메커니즘이지만 작은 문제가 있습니다. Type 및 MemberInfo에서 파생된 개체에는 많은 메모리가 필요합니다. 애플리케이션에 이러한 클래스가 너무 많이 포함되어 있지만 가끔씩만 사용하는 경우 애플리케이션의 메모리가 빠르게 증가하여 애플리케이션 성능에 영향을 미칩니다.

내부적으로 CLR은 이 정보를 더욱 압축된 형식으로 나타냅니다. CLR은 단순히 개발자의 삶을 더 쉽게 만들기 위해 응용 프로그램에 대한 이러한 개체를 만듭니다. CLR에는 런타임에 이러한 큰 개체가 필요하지 않습니다. 많은 수의 Type 및 MemberInfo 파생 개체를 캐시해야 하는 경우 개발자는 개체 대신 런타임 핸들을 사용하여 작업 세트(메모리 점유)를 줄일 수 있습니다. FCL은 세 가지 런타임 핸들 유형(모두 시스템 네임스페이스에 있음), RuntimeTypeHandle, RuntimeFieldHandle 및 RumtimeMethodHandle을 정의합니다. 세 가지 유형은 모두 값 유형이며 IntPtr인 하나의 필드만 포함하므로 이러한 유형의 인스턴스는 메모리를 상당히 절약합니다. ItPtr 필드는 AppDomain의 로더 힙에 있는 유형, 필드 또는 메서드를 참조하는 핸들입니다. 변환 방법:

  • 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 파생 개체를 캐시해야 하는 경우 개발자는 개체 대신 런타임 핸들을 사용하여 작업 세트(메모리 점유)를 줄일 수 있습니다. FCL은 세 가지 런타임 핸들 유형(모두 시스템 네임스페이스에 있음), RuntimeTypeHandle, RuntimeFieldHandle 및 RumtimeMethodHandle을 정의합니다. 세 가지 유형은 모두 값 유형이며 IntPtr인 하나의 필드만 포함하므로 이러한 유형의 인스턴스는 메모리를 상당히 절약합니다. ItPtr 필드는 AppDomain의 로더 힙에 있는 유형, 필드 또는 메서드를 참조하는 핸들입니다. 변환 방법:

  • 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) !


성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.