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.
144 lines
3.8 KiB
144 lines
3.8 KiB
1 month ago
|
/*
|
||
|
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();
|
||
|
}
|
||
|
}
|
||
|
}
|