好答案。我要补充一点,Java 取决于堆栈或堆内存位置的使用。C# 也是如此。使用原始指针的想法是来自 C 代码背景的 C# 的补充。尽管 C# 和 C/C++ 不是同一种代码语言,但它们确实有一些共同的语义。使用“不安全”代码的想法允许您避免将大型对象保留在每个运行时实例(对于 C# 每个 CLR,对于 Java 每个 JVM 实例)的内存限制为大约 2GB 的堆上,而不会因垃圾收集而导致性能急剧下降。在某些情况下,您可以使用 C# 的能力来利用不安全或手动管理的内存指针来解决这样一个事实,即没有那么多第三方工具可以解决堆外缓存等问题。
我要提醒的是,如果您确实使用了不安全的代码,请务必熟悉“一次性类型”和“终结器”。这可能是一种相当先进的做法,不正确处理对象的后果与使用 C 代码的后果相同……可怕的内存泄漏。后果是您的应用程序内存不足并且它崩溃了(不好)。这就是为什么 C# 默认不允许使用它,并且您需要使用“不安全”关键字覆盖手动控制指针的任何使用。这确保了任何手动处理的内存都是有意的。在处理“不安全”关键字时戴上你的 C 代码帽子。
在 Andrew Troelsen 的“Pro C# 2010 和 .Net 平台”中的“理解对象生命周期”一章中对此进行了很好的参考。如果您更喜欢在线参考,请参阅 MSDN 网站实现 Finalize 和 Dispose 以清理非托管资源
最后一点 - 非托管内存在对象的终结器部分 (~ObjectName(){...}) 中释放。这些模式确实会增加性能开销,因此如果您正在处理较低延迟的场景,最好让对象保持轻量级。如果您正在处理人类响应,那么您应该在绝对必要的情况下考虑这一点。