SORU
6 Temmuz 2011, ÇARŞAMBA


Önbellekleme yansıma verileri

Önbellek pahalı yansıma verileri elde etmek için en iyi yolu nedir? Örneğin en hızlı onlar aynı tür tekrar karşılaşmak her zaman yansıtmak için gereksiz önbellek böyle bir bilgi serializers. Hatta türünden alıyorlar ve dinamik bir yöntem oluşturmak olabilir.

Önce .net 4

Geleneksel olarak bunun için normal statik bir sözlük kullandım. Örneğin:

private static ConcurrentDictionary<Type, Action<object>> cache;

public static DoSomething(object o)
{
    Action<object> action;
    if(cache.TryGetValue(o.GetType(), out action)) //Simple lookup, fast!
    {
        action(o);
    }
    else
    {
        // Do reflection to get the action
        // slow
    }
} 

Bu bellek biraz sızdırıyor ama Tipi ve türlerine göre yalnızca bir kez olarak uzun AppDomain olarak yaşayan bu yana bir sorun olduğunu düşünmedim.

Beri .net 4

Ama şimdi .net 4 Collectible Assemblies for Dynamic Type Generation tanıttı. Eğer ben hiç bir nesne tahsil mecliste kabul edilmiştir DoSomething kullanılan montaj boşalttığınız götürmez. Ah.

Bilgileri yazın başına önbellek için en iyi yolu nedir .bu sorunu muzdarip olmadığını net 4? Aklıma en kolay çözümdür

private static ConcurrentDictionary<WeakReference, TCachedData> cache.

Ama bunu kullanmak zorunda kalırdım IEqualityComparer<T> çok garip bir şekilde davranır ve muhtemelen sözleşme de ihlal edecektir. Arama da olacağını nasıl emin değilim.

Başka bir fikir bir süre sonu zaman aşımı kullanın. En basit çözüm olabilir, ama sanki biraz kabalık oldu.


Bu tür genel parametre olarak verilen durumlarda, bu sorunu muzdarip değil, iç içe genel bir sınıf kullanabilirsiniz. Ama eğer bu tip bir değişken verilirse işe yaramıyor.

class MyReflection
{
    internal Cache<T>
    {
        internal static TData data;
    }

    void DoSomething<T>()
    {
        DoSomethingWithData(Cache<T>.data);
        //Obviously simplified, should have similar creation logic to the previous code.
    }
}

GüncellemeSadece yaşadım bir fikir anahtarı Type.AssemblyQualifiedName kullanıyor. Benzersiz bellekte tutarak olmadan bu tür tanımlamak gerekir. Hatta bu dize üzerinde başvuru kimlik kullanarak alabilirsiniz.

Bu çözüm ile kalan tek sorun, önbelleğe alınan değer türü için bir başvuru da tutabilir. Ve eğer zayıf bir referans kullanırsam bunun için en olası montaj bellekten alır önce uzakta sona erecek. Ve nasıl daha zayıf bir referans dışında normal bir başvuru Almak için emin değilim. Bazı testler yapmak istiyorum gibi görünüyor ve kıyaslama.

CEVAP
9 Temmuz 2011, CUMARTESİ


ConcurrentDictionary<WeakReference, CachedData> Bu durumda yanlıştır. WeakReference.Target==typeof(T) Bu bilgi türü T için önbellek için çalışıyoruz varsayalım. CachedData büyük olasılıkla typeof(T) için başvuru da içerir. Güçlü referansları zincir olacak Node<TKey, TValue> iç koleksiyonunda ConcurrentDictionary<TKey, TValue> mağaza öğeleri olarak: ConcurrentDictionary örnek ->Node örnek ->Value özelliği (CachedData örnek) ->typeof(T). Genel olarak Değerler Anahtarlarını başvuruları ne zaman imkansız bellek sızıntısı önlemek için bu durumda WeakReference.

ephemerons destek için böyle bir senaryo olası bellek sızıntısı olmadan yapmak için gerekli oldu. Çok şükür .NET 4.0 onları destekler ve ConditionalWeakTable<TKey, TValue> dersimiz var. Senin görevin yakın olduğunu tanıtmak reasons gibi görünüyor.

Bu yaklaşım ayrıca Yazın için başvuru tam olarak Derleme yüklü olduğu sürece yaşayacak gibi sorun güncelleme sözü çözer.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Evan Coury

    Evan Coury

    29 NİSAN 2007
  • Machinima

    Machinima

    17 Ocak 2006
  • USI Events

    USI Events

    6 AĞUSTOS 2013