C#中设计一个 ListPool 的方案

2021-03-06 16:29

阅读:570

标签:mem   min   void   lock   aci   dex   最大   sys   ack   

1、回顾一下有关List的几个知识点。

    点1: 注意理解 Capacity 与 Count 的不同之处。

    点2: 执行 TrimExcess() 方法可将容量设置为 List 中元素的实际数目。

    点3: List的 Capacity (注意理解与 Count 的不同之处)扩充是以 4 的倍数来扩充的。

    点4: 执行完 Clear() 方法后,Capacity 是不会变化的。

1 Listint> list = new Listint>();
2 Console.WriteLine(list.Capacity);   // 0
3 list.Add(1);
4 Console.WriteLine(list.Capacity);   // 4

2、ListPool方案:

  1 using System;
  2 using System.Collections.Generic;
  3 
  4 public interface IListPoolBase
  5 {
  6     void DoClear(int nowSeconds);
  7 }
  8 
  9 public class ListPoolItem : IListPoolBase
 10 {
 11     static int intervalTime = 30;  //清理池子的时间间隔(单位 : 秒)
 12     public List> pool;      //用List而不用Stack是因为在回收的时候,当pool达到上限的时候,要替换到 Capacity 最大的那个,用 Stack 无法自主替换
 13     public int lastUsedSeconds;
 14 
 15     public ListPoolItem(int initSize)
 16     {
 17         lastUsedSeconds = (int)(DateTime.Now.Ticks / TimeSpan.TicksPerSecond);
 18         pool = new List>(initSize);
 19     }
 20 
 21     //长时间不用,清理一下池子
 22     public void DoClear(int nowSeconds)
 23     {
 24         if (pool.Count > 0)
 25         {
 26             int durationNotUse = nowSeconds - lastUsedSeconds;
 27             if (durationNotUse >= intervalTime)
 28             {
 29                 pool.Clear();
 30             }
 31         }
 32     }
 33 
 34     public void Use()
 35     {
 36         lastUsedSeconds = (int)(DateTime.Now.Ticks / TimeSpan.TicksPerSecond);
 37     }
 38 }
 39 
 40 public static class ListPool 41 {
 42     public static int maxPoolSize = 4;
 43     static ListPoolItem poolItem;
 44 
 45     static ListPool()
 46     {
 47         poolItem = new ListPoolItem(maxPoolSize);
 48         ListPoolManager.Register(poolItem);
 49     }
 50 
 51     public static List Get()
 52     {
 53         lock (poolItem)
 54         {
 55             poolItem.Use();
 56             List> pool = poolItem.pool;
 57             int poolSize = pool.Count;
 58             if (poolSize > 0)
 59             {
 60                 List list = pool[poolSize - 1];
 61                 pool.RemoveAt(poolSize - 1);
 62                 return list;
 63             }
 64             else
 65             {
 66                 return new List();
 67             }
 68         }
 69     }
 70 
 71     public static void Release(ref List list)
 72     {
 73         if (null == list) return;
 74         lock (poolItem)
 75         {
 76             poolItem.Use();
 77             List> pool = poolItem.pool;
 78             List _list = list;
 79             list = null;
 80             if (pool.Contains(_list))
 81                 return;
 82             _list.Clear();
 83 
 84             //当_List的开辟的容量过大的时候,需要考虑到无用的容量,之所以加这个判断而不是直接清除,是为了避免反复的开辟空间
 85             if (_list.Capacity >= 4096)
 86             {
 87                 _list.TrimExcess();
 88             }
 89 
 90             int poolSize = pool.Count;
 91             //当pool的容量达到最大的时候,替换掉容量最大的那个
 92             if (poolSize >= maxPoolSize)
 93             {
 94                 int replaceIndex = -1;
 95                 int maxCapacity = _list.Capacity;
 96                 for (int i = 0; i i)
 97                 {
 98                     List curList = pool[i];
 99                     if (curList.Capacity > maxCapacity)
100                     {
101                         replaceIndex = i;
102                         maxCapacity = curList.Capacity;
103                     }
104                 }
105 
106                 if (replaceIndex >= 0)
107                 {
108                     pool[replaceIndex] = _list;
109                 }
110                 return;
111             }
112 
113             pool.Add(_list);
114         }
115     }
116 }
117 
118 //检测ListPool的使用情况
119 public static class ListPoolManager
120 {
121     static int _timerMS;
122     static int _minTriggerTimeMS = 3000;  //执行检测的时间间隔
123     static List listPool = new List();
124 
125     public static void Register(IListPoolBase poolItem)
126     {
127         listPool.Add(poolItem);
128     }
129 
130     //在主线程中做检测
131     public static void DoTracer(int deltaTimeMS)
132     {
133         _timerMS += deltaTimeMS;
134         //降低执行检测的频率
135         if (_timerMS  _minTriggerTimeMS)
136             return;
137 
138         _timerMS = 0;
139 
140         int nowSeconds = (int)(DateTime.Now.Ticks / TimeSpan.TicksPerSecond);
141         for (int i = 0; i i)
142         {
143             listPool[i].DoClear(nowSeconds);
144         }
145     }
146 }

C#中设计一个 ListPool 的方案

标签:mem   min   void   lock   aci   dex   最大   sys   ack   

原文地址:https://www.cnblogs.com/luguoshuai/p/12859369.html


评论


亲,登录后才可以留言!