Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/294.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 内存泄漏?顺便说一句,IEnumerable<;字节[]>;数组到非托管函数作为字节**参数_C#_Memory Leaks_Interop_Unmanaged_Managed - Fatal编程技术网

C# 内存泄漏?顺便说一句,IEnumerable<;字节[]>;数组到非托管函数作为字节**参数

C# 内存泄漏?顺便说一句,IEnumerable<;字节[]>;数组到非托管函数作为字节**参数,c#,memory-leaks,interop,unmanaged,managed,C#,Memory Leaks,Interop,Unmanaged,Managed,这是分配和释放传递到非托管dll的托管数据句柄的正确方法吗 存在具有导出函数的非托管dll void Function(byte** ppData, int N); 我需要传递它IEnumerable AFID var handles = afids.Select(afid => GCHandle.Alloc(afid, GCHandleType.Pinned)); var ptrs = handles.Select(h => h.AddrOfPinnedObject()); In

这是分配和释放传递到非托管dll的托管数据句柄的正确方法吗

存在具有导出函数的非托管dll

void Function(byte** ppData, int N);
我需要传递它
IEnumerable AFID

var handles = afids.Select(afid => GCHandle.Alloc(afid, GCHandleType.Pinned));
var ptrs = handles.Select(h => h.AddrOfPinnedObject());
IntPtr[] afidPtrs = ptrs.ToArray();
uint N = (uint)afidPtrs.Length;

Function(afidPtrs, N);

handles.ToList().ForEach(h => h.Free());
我管理内存泄漏,并在即时窗口中获取sos.dll

DOMAIN(00275030):HANDLE(Pinned):3ea2c0:Root:  17a8d190(System.Byte[])
函数定义为:

[DllImport("My.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
static extern unsafe internal int Function(IntPtr[] ppData, int N);
控制台应用程序的错误代码段:

static void Main(string[] args)
{
    while (!Console.KeyAvailable)
    {
        IEnumerable<byte[]> data = CreateEnumeration(100);
        PinEntries(data);
        Thread.Sleep(900);
        Console.Write(String.Format("gc mem: {0}\r", GC.GetTotalMemory(true)));
    }
}

static IEnumerable<byte[]> CreateEnumeration(int size)
{
    Random random = new Random();
    IList<byte[]> data = new List<byte[]>();
    for (int i = 0; i < size; i++)
    {
        byte[] vector = new byte[12345];
        random.NextBytes(vector);
        data.Add(vector);
    }
    return data;
}

static void PinEntries(IEnumerable<byte[]> data)
{
    var handles = data.Select(d => GCHandle.Alloc(d, GCHandleType.Pinned));
    var ptrs = handles.Select(h => h.AddrOfPinnedObject());
    IntPtr[] dataPtrs = ptrs.ToArray();
    Thread.Sleep(100); // unmanaged function call taking byte** data
    handles.ToList().ForEach(h => h.Free());
}
static void PinEntries(IEnumerable<byte[]> data)
{
    IEnumerable<GCHandle> handles = CreateHandles(data);
    IntPtr[] ptrs = GetAddrOfPinnedObjects(handles);
    Thread.Sleep(100); // unmanaged function call taking byte** data
    FreeHandles(handles);
}

static IEnumerable<GCHandle> CreateHandles(IEnumerable<byte[]> data)
{
    IList<GCHandle> handles = new List<GCHandle>();
    foreach (byte[] vector in data)
    {
            GCHandle handle = GCHandle.Alloc(vector, GCHandleType.Pinned);
            handles.Add(handle);
    }
    return handles;
}

static IntPtr[] GetAddrOfPinnedObjects(IEnumerable<GCHandle> handles)
{
    IntPtr[] ptrs = new IntPtr[handles.Count()];
    for (int i = 0; i < ptrs.Length; i++)
            ptrs[i] = handles.ElementAt(i).AddrOfPinnedObject();
    return ptrs;
}

static void FreeHandles(IEnumerable<GCHandle> handles)
{
    foreach (GCHandle handle in handles)
            handle.Free();
}
static void Main(字符串[]args)
{
而(!Console.KeyAvailable)
{
IEnumerable数据=CreateEnumeration(100);
松中心(数据);
睡眠(900);
Write(String.Format(“gcmem:{0}\r”,gc.getTotalMemy(true));
}
}
静态IEnumerable CreateEnumeration(整数大小)
{
随机=新随机();
IList数据=新列表();
对于(int i=0;iGCHandle.Alloc(d,GCHandleType.pinted));
var ptrs=handles.Select(h=>h.addrofPindedObject());
IntPtr[]dataPtrs=ptrs.ToArray();
Thread.Sleep(100);//非托管函数调用获取字节**数据
handles.ToList().ForEach(h=>h.Free());
}
控制台应用程序的正确代码段:

static void Main(string[] args)
{
    while (!Console.KeyAvailable)
    {
        IEnumerable<byte[]> data = CreateEnumeration(100);
        PinEntries(data);
        Thread.Sleep(900);
        Console.Write(String.Format("gc mem: {0}\r", GC.GetTotalMemory(true)));
    }
}

static IEnumerable<byte[]> CreateEnumeration(int size)
{
    Random random = new Random();
    IList<byte[]> data = new List<byte[]>();
    for (int i = 0; i < size; i++)
    {
        byte[] vector = new byte[12345];
        random.NextBytes(vector);
        data.Add(vector);
    }
    return data;
}

static void PinEntries(IEnumerable<byte[]> data)
{
    var handles = data.Select(d => GCHandle.Alloc(d, GCHandleType.Pinned));
    var ptrs = handles.Select(h => h.AddrOfPinnedObject());
    IntPtr[] dataPtrs = ptrs.ToArray();
    Thread.Sleep(100); // unmanaged function call taking byte** data
    handles.ToList().ForEach(h => h.Free());
}
static void PinEntries(IEnumerable<byte[]> data)
{
    IEnumerable<GCHandle> handles = CreateHandles(data);
    IntPtr[] ptrs = GetAddrOfPinnedObjects(handles);
    Thread.Sleep(100); // unmanaged function call taking byte** data
    FreeHandles(handles);
}

static IEnumerable<GCHandle> CreateHandles(IEnumerable<byte[]> data)
{
    IList<GCHandle> handles = new List<GCHandle>();
    foreach (byte[] vector in data)
    {
            GCHandle handle = GCHandle.Alloc(vector, GCHandleType.Pinned);
            handles.Add(handle);
    }
    return handles;
}

static IntPtr[] GetAddrOfPinnedObjects(IEnumerable<GCHandle> handles)
{
    IntPtr[] ptrs = new IntPtr[handles.Count()];
    for (int i = 0; i < ptrs.Length; i++)
            ptrs[i] = handles.ElementAt(i).AddrOfPinnedObject();
    return ptrs;
}

static void FreeHandles(IEnumerable<GCHandle> handles)
{
    foreach (GCHandle handle in handles)
            handle.Free();
}
static void PinEntries(IEnumerable数据)
{
IEnumerable handles=CreateHandles(数据);
IntPtr[]ptrs=getAddRofPinnedObject(句柄);
Thread.Sleep(100);//非托管函数调用获取字节**数据
自由手柄(手柄);
}
静态IEnumerable CreateHandles(IEnumerable数据)
{
IList handles=new List();
foreach(数据中的字节[]向量)
{
GCHandle=GCHandle.Alloc(向量,GCHandleType.pinted);
句柄。添加(句柄);
}
返回手柄;
}
静态IntPtr[]GetAddRofPinnedObject(IEnumerable句柄)
{
IntPtr[]ptrs=newintptr[handles.Count()];
对于(int i=0;i
请注意,添加了ToList()以强制枚举到集合中


请注意,添加了ToList()以强制枚举到集合中。

您可以演示如何在C#中定义互操作函数吗?好的,添加了。读取非托管代码中的数据时没有问题,在调试生成中使用
\u crtdumpmomeryleaks()
验证的非托管dll中也没有任何泄漏。请尝试手动指定静态外部不安全的内部int函数([MarshalAs(LPArray,ArraySubType=U4)]IntPtr[]ppData,int N);(对于32位代码)非托管函数调用没有问题。dll和exe显式编译为32位。如果您运行附加的代码段,那么在任何情况下,mem泄漏都会增加。这是一个固定的句柄,它并没有以某种方式释放。您能展示一下如何在C#中定义互操作功能吗?好的,我们已经添加了。读取非托管代码中的数据时没有问题,在调试生成中使用
\u crtdumpmomeryleaks()
验证的非托管dll中也没有任何泄漏。请尝试手动指定静态外部不安全的内部int函数([MarshalAs(LPArray,ArraySubType=U4)]IntPtr[]ppData,int N);(对于32位代码)非托管函数调用没有问题。dll和exe显式编译为32位。如果您运行附加的代码段,那么在任何情况下,mem泄漏都会增加。这是一个没有被释放的钉住的句柄。顺便说一句,我对复制代码的赞扬,你让它很容易帮助你。非常感谢,就在我看到你的答案之前,我修改了我的代码片段,删除了所有LINQ的东西,问题已经解决了。我的灵感来自LINQ代码的简洁性,这让我陷入了GCHandle陷阱。正如我从文章中看到的,这是在.NET应用程序中进行泄漏的非常有效的方法:)我对复制代码的赞扬,顺便说一句,您使帮助您变得很容易。非常感谢,就在我看到你的答案之前,我修改了我的代码片段,删除了所有LINQ内容,问题已经解决了。我的灵感来自LINQ代码的简洁性,这让我陷入了GCHandle陷阱。正如我从文章中看到的,这是在.NET应用程序中进行泄漏的非常有效的方法:)