MemoryFailPoint: alokowanie dużej ilości pamięci

Czasami zachodzi potrzeba wykonania krytycznego kodu, który zużywa dużo zasobów. Podobnie jak w CER, nie chcemy wykonywać kodu jeśli wiemy, że nie ma wystarczającej pamięci. W .NET istnieje klasa MemoryFailPoint, która potrafi z góry “zaalokować” określoną pamięć.

public sealed class MemoryFailPoint : CriticalFinalizerObject, IDisposable 
{
    public MemoryFailPoint(Int32 sizeInMegabytes);
    ~MemoryFailPoint();
    public void Dispose();
}

MemoryFailPoint sprawdzi czy jest dostępna pamięć. Jeśli jej nie ma, zostanie uruchomiony GC, aby zwolnić zbędne zasoby. Jeśli wciąż nie ma wystarczającej pamięci wyrzucany jest wyjątek InsufficientMemoryException.  W przypadku gdy konstruktor nie spowodował wyjątku to znaczy, że istnieją wystarczające zasoby pamięciowe. Należy pamiętać, że MemoryFailPoint nie alokuje tak naprawdę pamięci co oznacza, że wciąż wykonanie następnego kodu może spowodować OutOfMemoryException. MemoryFailPoint służy jedynie do zminimalizowania ryzyka i należy wziąć to pod uwagę podczas implementacji algorytmu.

Po wykonaniu algorytmu należy również wywołać Dispose aby zwolnić MemoryFailPoint. Dispose tak naprawdę odejmuje od pola statycznego wartość zarezerwowanej pamięci w sposób thread-safe.

try 
{
    using (MemoryFailPoint mfp = new MemoryFailPoint(5000)) 
    {
      // wykonanie algorytmu potrzebujacego duzo pamieci
    } 
}
catch (InsufficientMemoryException e) 
{
     // niestety nie ma wystarczajacej pamieci i nie ma co nawet algorytmu rozpoczynac.
}

Minimalną wartością, którą możemy przekazać do MFP jest 16. Również wszelkie wyższe wartości muszą być wielokrotnością liczby 16 lub po prostu będą odpowiednio zaokrąglone. Warto rozważyć użycie tej klasy dla np. bibliotek graficznych. Pozwolenie aplikacji na zdławienie wszelkich dostępnych zasobów nie jest dobrym pomysłem i wtedy zwykle jedynym rozsądnym wyjściem jest zakończenie procesu.

One thought on “MemoryFailPoint: alokowanie dużej ilości pamięci”

Leave a Reply

Your email address will not be published.