C++/CLI中的垃圾回收,C#混合代码

本文关键字:混合 代码 CLI C++ | 更新日期: 2023-09-27 18:01:10

我通过引用将一个数组从C#传递给C++/CLI,用作out参数。我的代码如下:

C#

ushort[] a = new ushort[1];
cppclr.method(ref a);

C++/CLI

void method(array<ushort>^% a)
{
   a = gcnew array<ushort>(5);
   a[0] = 1;
   a[1] = 2;
   a[2] = 3;
}

代码编译良好,不会产生错误。然而,我很困惑我在C#中创建的数组是否已经被垃圾回收处理了?我感到困惑的是,由于我在C++/CLI中分配了一个新内存,所以前面的引用会丢失,应该由垃圾回收来处理。该程序没有显示任何内存泄漏。我需要用其他方式来处理这种情况吗?

C++/CLI中的垃圾回收,C#混合代码

一切都在处理之中。无论您运行的是C#、C++/CLI还是任何其他.NET语言,都是相同的运行时在后台执行这两种语言。因此,您可以为两者获得相同的GC。

在使用gcnew时,您使用了运行时的托管内存分配器。如果您在C++/CLI中将new与非托管数组一起使用,那么之后必须使用delete[]运算符释放它。

C#中的垃圾回收对于托管资源是自动的,所以您不应该担心它们。我在C++方面没有太多经验,但据我所知,您正在使用托管C++

.NET Framework的垃圾收集器管理分配和释放应用程序的内存。每次创建新对象,公共语言运行库为该对象分配内存来自托管堆。只要托管堆,运行时继续为新对象分配空间。然而,记忆并不是无限的。最终,垃圾收集器必须执行收集以释放一些内存。垃圾收集器的优化引擎确定执行收集,基于正在进行的分配。当垃圾收集器执行收集,它检查托管中的对象应用程序不再使用的堆,并执行必要的操作来回收它们的内存。

MSDN源垃圾回收

您应该只关心非托管资源。(对于C#,它们继承了IDisposable,您应该调用Dispose((方法,对于C++,调用delete[],就像@Lucas提到的那样(。

你也可以检查这个问题:跨C#和C++/CLI对象的垃圾回收