大学IT网 - 最懂大学生的IT学习网站! QQ资料交流群:367606806
当前位置:大学IT网 > C#技巧 > 《你不常用的c#之一》:略谈unsafe

《你不常用的c#之一》:略谈unsafe

关键词:c#unsafe  阅读(899) 赞(56)

[摘要]《你不常用的c#之一》:略谈unsafe。

msdn里讲到:

“在 C# 中很少需要使用指针,但仍有一些需要使用的情况。例如,在下列情况中使用允许采用指针的不安全上下文是正确的:

处理磁盘上的现有结构

涉及内部包含指针的结构的高级 COM 或平台调用方案

性能关键代码

对于第一和第二点,主要是调win32的api。

但是“性能关键代码”这个非常重要。我来举例引申一下。

我们都知道像飞信这种大型IM服务端,难免会面临大量的字符处理(协议报文)。

如果同时在线100多万,而且大家都同时进行会话,服务端的程序如果对内存回收不好,那肯定会crash.

飞信服务端是.net的,所以就拉扯一下这个例子。

不过你可以大胆猜测,它服务端肯定用了unsafe,不然顶不住这档子活!!

还是msdn上的demo:

以下示例使用指针将一个字节数组从 src 复制到 dst。用 /unsafe 选项编译此示例。

// fastcopy.cs
// compile with: /unsafe
using System;
class Test
{
// The unsafe keyword allows pointers to be used within
// the following method:
static unsafe void Copy(byte[] src, int srcIndex,
byte[] dst, int dstIndex, int count)
{
if (src == null || srcIndex < 0 ||
dst == null || dstIndex < 0 || count < 0)
{
throw new ArgumentException();
}
int srcLen = src.Length;
int dstLen = dst.Length;
if (srcLen - srcIndex < count ||
dstLen - dstIndex < count)
{
throw new ArgumentException();
}
// The following fixed statement pins the location of
// the src and dst objects in memory so that they will
// not be moved by garbage collection.
fixed (byte* pSrc = src, pDst = dst)
{
byte* ps = pSrc;
byte* pd = pDst;
// Loop over the count in blocks of 4 bytes, copying an
// integer (4 bytes) at a time:
for (int n =0 ; n < count/4 ; n++)
{
*((int*)pd) = *((int*)ps);
pd += 4;
ps += 4;
}
// Complete the copy by moving any bytes that weren’t
// moved in blocks of 4:
for (int n =0; n < count%4; n++)
{
*pd = *ps;
pd++;
ps++;
}
}
}
static void Main(string[] args)
{
byte[] a = new byte[100];
byte[] b = new byte[100];
for(int i=0; i<100; ++i)
a[i] = (byte)i;
Copy(a, 0, b, 0, 100);
Console.WriteLine(”The first 10 elements are:”);
for(int i=0; i<10; ++i)
Console.Write(b[i] + ” “);
Console.WriteLine(”/n”);
}
}

请注意使用了 unsafe 关键字,这允许在 Copy 方法内使用指针。

fixed 语句用于声明指向源和目标数组的指针。它锁定 src 和 dst 对象在内存中的位置以便使其不会被垃圾回收移动。当 fixed 块完成后,这些对象将被解除锁定。

通过略过数组界限检查,不安全代码可提高性能。

fixed 语句允许您获取指向字节数组使用的内存的指针,并且标记实例,以便垃圾回收器不会移动它。

在 fixed 块的末尾,将标记该实例以便可以移动它。此功能称为声明式锁定。锁定的好处是系统开销非常小,除非在 fixed 块中发生垃圾回收(但此情况不太可能发生)。

对头,fixed 内我只分配我自己的内存,用完就释放,从不霸占平民土地,不多征收平民余粮!!

对于如果你要是等着GC来跟你处理,它寻根寻址还得点时候呢。。。。。



相关评论