You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

143 lines
3.8 KiB

/*
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<byte[]> m_queue = new ConcurrentQueue<byte[]>();
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];
}
/// <summary>
/// 释放内存的时候加入队列,下次使用
/// </summary>
/// <param name="buffer"></param>
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;
}
}
/// <summary>
/// 这个byte[]如果只考虑消息的话,可以用一个大byte[]数组代替,返回数组的其中一段数据
/// 问题是要考虑线程安全,以后可以试试,有没有效率高的办法
/// </summary>
public class ByteArrayCacheMgr : Singleton<ByteArrayCacheMgr>
{
//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();
}
}
}