/* Sog 游戏基础库 2016 by zouwei */ using System; using System.Collections.Concurrent; using System.Text; using System.Threading; namespace Sog.Memory { public class ByteArrayCache { public int FixedSize { get; } private long MallocCount; private long FreeCount; private ConcurrentQueue m_queue = new ConcurrentQueue(); public ByteArrayCache(int size) { this.FixedSize = size; } public byte[] Malloc() { Interlocked.Increment(ref MallocCount); //不要用Count > 0来判断,效率低 if (m_queue.IsEmpty == false) { byte[] buffer; //只尝试一次,失败就算了 if(m_queue.TryDequeue(out buffer)) { return buffer; } } //直接向系统申请内存,大小是固定的 return new byte[FixedSize]; } /// /// 释放内存的时候加入队列,下次使用 /// /// public void Free(byte[] buffer) { Interlocked.Increment(ref FreeCount); m_queue.Enqueue(buffer); } public int GetCacheCount() { return m_queue.Count; } public long GetMallocCount() { return MallocCount; } public long GetFreeCount() { return FreeCount; } } /// /// 这个byte[]如果只考虑消息的话,可以用一个大byte[]数组代替,返回数组的其中一段数据 /// 问题是要考虑线程安全,以后可以试试,有没有效率高的办法 /// public class ByteArrayCacheMgr : Singleton { //32,64,128,256,512,1K,2K,4K,8K,16K,32K,64K private ByteArrayCache[] m_cacheArray = new ByteArrayCache[12]; public ByteArrayCacheMgr() { int size = 32; for(int i=0; i< m_cacheArray.Length ;i++ ) { m_cacheArray[i] = new ByteArrayCache(size); size = size * 2; } } public byte[] Malloc(int size) { for(int i=0; i< m_cacheArray.Length; i++) { if(m_cacheArray[i].FixedSize >= size) { return m_cacheArray[i].Malloc(); } } //太大的就不管了,直接向系统申请,这个上层最好自己判断,不要调用这个 return new byte[size]; } public void Free(byte[] buffer) { for (int i = 0; i < m_cacheArray.Length; i++) { if (m_cacheArray[i].FixedSize == buffer.Length) { m_cacheArray[i].Free(buffer); break; } } } public string StatInfo() { StringBuilder sb = new StringBuilder(512); sb.Append("ByteArrayCacheMgr"); int totalcount = 0; for (int i = 0; i < m_cacheArray.Length; i++) { var cache = m_cacheArray[i]; totalcount += cache.GetCacheCount(); sb.Append(" ["); sb.Append(cache.FixedSize); sb.Append("]:"); sb.Append(cache.GetCacheCount()); sb.Append(" ("); sb.Append(cache.GetMallocCount()); sb.Append("-"); sb.Append(cache.GetFreeCount()); sb.Append(")"); } sb.Append("total:"); sb.Append(totalcount); return sb.ToString(); } } }