Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/326.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#内存管理:不安全的关键字和指针_C#_Memory Management_Pointers_Keyword_Unsafe - Fatal编程技术网

C#内存管理:不安全的关键字和指针

C#内存管理:不安全的关键字和指针,c#,memory-management,pointers,keyword,unsafe,C#,Memory Management,Pointers,Keyword,Unsafe,在C#中使用不安全关键字使用指针会产生什么后果(正面/负面)?例如,垃圾收集会变成什么样子,性能的增益/损耗是什么,与其他语言相比,性能的增益/损耗是什么手动内存管理,危险是什么,在什么情况下使用这种语言功能真的是合理的,编译的时间长吗 引用《2008年专业杂志》: “使用 指针是: 向后兼容性-尽管 .NET运行时仍然可以 调用本机Windows API函数,以及 对于某些操作,这可能是 完成任务的唯一方法。 这些API函数通常是 用C语言编写,通常需要 指针作为参数。但是,在 在许多情况下,

C#中使用不安全关键字使用指针会产生什么后果(正面/负面)?例如,垃圾收集会变成什么样子,性能的增益/损耗是什么,与其他语言相比,性能的增益/损耗是什么手动内存管理,危险是什么,在什么情况下使用这种语言功能真的是合理的,编译的时间长吗

引用《2008年专业杂志》:

“使用 指针是:

  • 向后兼容性-尽管 .NET运行时仍然可以 调用本机Windows API函数,以及 对于某些操作,这可能是 完成任务的唯一方法。 这些API函数通常是 用C语言编写,通常需要 指针作为参数。但是,在 在许多情况下,可以编写 DllImport声明的方式 避免使用指针;例如, 通过使用System.IntPtr类
  • 性能-在速度最快的场合 重要的是,指针可以提供 路由到优化性能。如果 知道你在做什么,你可以 确保数据被访问或删除 以最有效的方式操纵。 但是,请注意,更多情况下 除此之外,还有其他方面的问题 你的代码,你可以使必要的 性能改进,无需 解析指针。尝试使用 用于查找瓶颈的代码探查器 在您的代码中,一个带有可视 工作室2008。”
  • 如果您使用指针,您的代码将需要更高级别的信任才能执行,如果用户不同意,您的代码将不会运行

    最后一句话:

    “我们强烈建议不要使用 不必要的指针,因为它会 不仅更难编写和调试, 但它也会使记忆失效 由制造商进行的型式安全检查 CLR。“


    我可以给你一个值得使用的情况:


    我必须逐像素生成位图<代码>绘图.位图.SetPixel()太慢了。因此,我构建了自己的位图数据的托管
    数组
    ,并使用
    safe
    获取
    IntPtr

    正如Conrad已经提到的,在某些情况下,不安全地访问C中的内存是有用的。它们没有那么多,但有一些:

    • 使用
      Bitmap
      进行操作几乎是一个典型的例子,您需要通过使用
      不安全的
      获得一些额外性能

    • 与旧API(如WinAPI或本机C/C++DLL)的互操作性是另一个非常有用的领域,
      unsafe
      ——例如,您可能希望调用一个接受/返回非托管指针的函数

    另一方面,您可以使用编写大多数内容,这隐藏了方法调用中的许多不安全操作。这会稍微慢一点,但是如果您想避免使用
    不安全的
    (或者如果您使用的是没有
    不安全的VB.NET,那么这是一个选项)

    积极后果: 因此,C#中存在的
    不安全
    的主要积极后果是,您可以更轻松地编写一些代码(互操作性),也可以更高效地编写一些代码(使用位图或使用数组进行一些繁重的数值计算-尽管我不太确定第二个)

    负面后果:当然,使用
    不安全
    ,您必须付出一定的代价:

    • 不可验证代码:使用
      不安全
      功能编写的代码变得不可验证,这意味着您的代码可能以任何方式危害运行时。在完全信任的情况下(例如,不受限制的桌面应用程序),这不是一个大问题-你只是没有所有好的.NET CLR保证。但是,您不能在受限制的环境中运行应用程序,例如公共web托管、Silverlight或部分信任(例如,从网络运行的应用程序)

    • 垃圾收集器在使用不安全的
      时也需要小心。通常允许GC重新定位托管堆上的对象(以保持内存碎片整理)。当您获取指向某个对象的指针时,需要使用
      fixed
      关键字告诉GC在您完成之前无法移动该对象(这可能会影响垃圾收集的性能,当然,这取决于具体的场景)


    我猜想,如果C#不必与较旧的代码进行互操作,它可能不会支持
    不安全的
    (而像Singularity这样的研究项目试图创建基于托管语言的更可验证的操作系统,显然不允许使用usnsafe代码)。然而,在现实世界中,
    不安全
    在某些(罕见的)情况下是有用的。

    垃圾收集对于长寿命对象来说效率很低。Net的垃圾收集器在大多数对象释放得相当快,并且一些对象“永远存在”的情况下工作得最好。问题是,寿命较长的对象只在完全垃圾收集期间释放,这会导致严重的性能损失。本质上,长寿物体很快进入第二代

    (有关更多信息,您可能需要阅读.Net的分代垃圾收集器:)

    在对象或内存使用将长期存在的情况下,手动内存管理将产生更好的性能,因为它可以释放到系统中,而不需要完全的垃圾收集

    实现某种基于单个大字节数组、结构和大量指针算法的内存管理系统,理论上可以提高性能