본문 바로가기
개발/기본) 기본기

기본기)c#) WeakReference Class

by 테샤르 2020. 11. 2.

WeakReference Class

c#에서의 가비지 수집에 의거해서 수집되는 항목에 포함될 수 있도록 개체의 연관성을 '약한 참조'의 형태로 선언하는 방식이다.

네임스페이스:System
어셈블리:System.Runtime.dll
using System;
using System.Collections.Generic;

public class Program
{
    public static void Main()
    {
        // Create the cache.
        int cacheSize = 50;
        Random r = new Random();
        Cache c = new Cache(cacheSize);

        string DataName = "";
        GC.Collect(0);

        // Randomly access objects in the cache.
        for (int i = 0; i < c.Count; i++) {
            int index = r.Next(c.Count);

            // Access the object by getting a property value.
            DataName = c[index].Name;
        }
        // Show results.
        double regenPercent = c.RegenerationCount/(double)c.Count;
        Console.WriteLine("Cache size: {0}, Regenerated: {1:P2}%", c.Count, regenPercent);
    }
}

public class Cache
{
    // Dictionary to contain the cache.
    static Dictionary<int, WeakReference> _cache;

    // Track the number of times an object is regenerated.
    int regenCount = 0;

    public Cache(int count)
    {
        _cache = new Dictionary<int, WeakReference>();

        // Add objects with a short weak reference to the cache.
       for (int i = 0; i < count; i++) {
            _cache.Add(i, new WeakReference(new Data(i), false));
        }
    }

    // Number of items in the cache.
    public int Count
    {
        get {  return _cache.Count; }
    }

    // Number of times an object needs to be regenerated.
    public int RegenerationCount
    {
        get { return regenCount; }
    }

    // Retrieve a data object from the cache.
    public Data this[int index]
    {
        get {
            Data d = _cache[index].Target as Data;
            if (d == null) {
                // If the object was reclaimed, generate a new one.
                Console.WriteLine("Regenerate object at {0}: Yes", index);
                d = new Data(index);
                _cache[index].Target = d;
                regenCount++;
            }
            else {
                // Object was obtained with the weak reference.
                Console.WriteLine("Regenerate object at {0}: No", index);
            }

            return d;
       }
    }
}

// This class creates byte arrays to simulate data.
public class Data
{
    private byte[] _data;
    private string _name;

    public Data(int size)
    {
        _data = new byte[size * 1024];
        _name = size.ToString();
    }

    // Simple property.
    public string Name
    {
        get { return _name; }
    }
}
// Example of the last lines of the output:
//
// ...
// Regenerate object at 36: Yes
// Regenerate object at 8: Yes
// Regenerate object at 21: Yes
// Regenerate object at 4: Yes
// Regenerate object at 38: No
// Regenerate object at 7: Yes
// Regenerate object at 2: Yes
// Regenerate object at 43: Yes
// Regenerate object at 38: No
// Cache size: 50, Regenerated: 94%

WeakReference (Object)를 선언하고 데이터를 연결하면 된다.

c#의 특성상. GC가 언제 호출될지는 모르기 때문에, GC가 호출되는 과정에서 수집할 수 있는 우선순위를 높여주는 방식으로 작업을 했었다. 지금은 WeakReference로 선언해서 작업하는 방식으로 변경을 해야겠다.

대부분의 메모리를 강한 참조를 해야하는 것들은 메모리 풀링의 형태로 구현을 하거나 static 하게 정의를 하는 게 확실한 것 같다.

 

참고 URL : [링크]

 

 ★

 

 

반응형

댓글