>source

나는 ConcurrentDictionary<String, String> 를 사용한다  많은 양의 데이터 (4500 000 항목)를 저장하고 여분의 메모리를 사용하고 싶지 않으므로 처음에 용량을 고정했습니다. 그러나 사전은 지정된 용량에 도달하기 전에 자동으로 커집니다.

저는 단지 500 개의 항목으로 만 문제를 보여주기 위해 코드의 작은 부분을 작성했습니다. 실제 용량을 제공하는 공공 재산을 찾지 못했기 때문에 개인 버킷 배열에 반영합니다 :

using System;
using System.Collections.Concurrent;
using System.Reflection;
namespace MemoryUsage
{
    class Program
    {
        static void Main(string[] args)
        {
            CapacityTest();
        }
        private static void CapacityTest()
        {
            int capacity = 500;
            ConcurrentDictionary<String, String> dict = new ConcurrentDictionary<string, string>(Environment.ProcessorCount, capacity);
            Console.WriteLine("{0} buckets", GetBucketCount(dict));
            for (int index = 0; index < capacity; index++)
                dict.AddOrUpdate(Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), (key, value) => value);
            Console.WriteLine("{0} buckets", GetBucketCount(dict));
            Console.ReadLine();
        }
        private static int GetBucketCount(ConcurrentDictionary<string, string> dict)
        {
            object tables = dict.GetType().GetField("m_tables", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(dict); // "_tables" with .NET Core, "m_tables" with .NET Framework
            object buckets = tables.GetType().GetField("m_buckets", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(tables); // "_buckets" with .NET Core, "m_buckets" with .NET Framework
            return ((Array)buckets).Length;
        }
    }
}

디스플레이 :

500 buckets at the beginning
1003 buckets at the end

500 buckets at the end 를 기대했다 . 처음에 항목 수를 알고 있기 때문에 추가 메모리 할당을 피하는 방법을 알고 있습니까?

  • 답변 # 1

    용량이 아닌 초기 용량입니다. 따라서 제한 할 수 없습니다.

    바퀴를 재발 명하지 말고 MemoryCache를 사용하십시오. 메모리가 부족한 경우 항목을 자동으로 삭제합니다. 실제로 메모리를 제어하려면 MemoryCache.CacheMemoryLimit를 사용하십시오.

  • 답변 # 2

    값의 분포와 관련이있는 것 같습니다 (잠금 메커니즘 최적화 또는 사용 된 트리 구조의 특성). . 프로세서 수 = 8 인 정수 세트 (0-7)로 코드를 사용해 보았습니다 .8 버킷 만 있습니다.

    dict.AddOrUpdate(index, index, (key, value) => value);
    
    

    그러나 키에 2를 곱하면 8 번 중 5 번 시도한 후에 17 개의 버킷이 있습니다.

관련 자료

  • 이전 Flutter에서 현재 경로를 보존하고 이전 경로를 팝
  • 다음 orgopenqaseleniumososprocess checkforerror 및 orgapachecommonsexecexecuteexception - selenium chromedriver에서 오류로 프로세스가 종료되었습니다