我目前正在研究使用 C++/CLI 来弥合托管 C# 和 native 非托管 C++ 代码之间的差距。我希望解决的一个特定问题是 C# 和 C++ 中不同数据类型的转换。
在阅读这种桥接方法的使用和所涉及的性能影响时,我想知道垃圾收集是如何工作的。具体来说,如果对象在“另一端”被引用/销毁,垃圾收集器将如何处理在任一端创建的对象的清理。
到目前为止,我已经在 StackOverflow 上阅读了各种文章和论坛问题和 MSDN ,这让我相信垃圾收集器在同一进程中运行时应该跨两种类型的代码工作——即如果一个对象是在 C# 中创建并传递给 C++/CLI 桥,它不会被收集直到引用两边都不再使用了。
在这种情况下,我的问题分为三个部分:
- 我得出的结论是否正确,垃圾收集器在同一进程中运行时跨代码的两个部分(C# 和 C++/CLI)工作?
- 关于 1:它在这种情况下如何工作(特别是在清理两个代码库引用的对象方面)。
- 对于如何监控垃圾收集器的事件是否有任何建议 - 即编写测试来检查何时发生垃圾收集;或监控垃圾收集器本身的程序。
我已经对垃圾收集器的一般工作原理有了一些了解,所以我在这里的问题是针对以下场景的:
组件
- 程序集 A - (用 C# 编写)
- 程序集 B - (用 C++/CLI 编写)
程序执行
- 对象
O
在程序集 A 中创建。 - 对象
O
被传递到 程序集 B 中的函数。 - 释放对程序集 A 中对象
O
的引用。 - 程序集 B 持有对对象
O
的引用。 - 执行结束(即通过程序退出)。
- 程序集 B 释放对对象
O
的引用。
在此先感谢您对这个问题的任何想法。如果需要进一步的信息或者有什么地方不够清楚,请告诉我。
编辑
最佳答案
当代码真正运行时,不会是C#或C++/CLI。所有这些都将是来自 C# 和 C++/CLI 的 IL 以及来自您与之互操作的 native 代码的机器代码。
因此您可以将部分问题重写为:
- 程序集 A -(IL,我们不知道它是用什么写的)
- 程序集 B -(IL,我们不知道它是用什么写的)
在托管对象中,所有这些对象都将按照相同的规则进行垃圾回收,除非您使用一种机制来阻止它 (GC.KeepAlive)。所有这些都可以在内存中移动,除非您固定它们(因为您正在将地址传递给非托管代码。
.NET Profiler 将为您提供一些有关垃圾回收的信息,以及性能监视器中的回收计数。
关于c# - 跨 C# 和 C++/CLI 对象的垃圾收集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8757937/