C# 如何";“归零”;并确保从内存中删除字符串

C# 如何";“归零”;并确保从内存中删除字符串,c#,string,xamarin,garbage-collection,C#,String,Xamarin,Garbage Collection,我理解垃圾收集的主要概念,即一旦一个特定对象不再有指针引用它,它就是“垃圾收集” 这是否意味着它已被释放,但它的值仍可供具有调试器/反汇编程序的用户读取(至少在写入该地址之前) 我知道对于大多数对象(那些在C#中实现IDisposable接口的对象),您可以调用Dispose()方法,并且非常确信内存永远不会被访问。但是字符串呢 我知道垃圾收集(在iOS中称为ARC)一旦达到0个引用,对象就会自行“处理”。我担心我的应用程序(我接管了大量的遗留代码)会有大量内存泄漏和强引用,我不希望PCI敏感数

我理解垃圾收集的主要概念,即一旦一个特定对象不再有指针引用它,它就是“垃圾收集”

这是否意味着它已被释放,但它的值仍可供具有调试器/反汇编程序的用户读取(至少在写入该地址之前)

我知道对于大多数对象(那些在
C#
中实现
IDisposable
接口的对象),您可以调用
Dispose()
方法,并且非常确信内存永远不会被访问。但是字符串呢

我知道垃圾收集(在iOS中称为
ARC
)一旦达到0个引用,对象就会自行“处理”。我担心我的应用程序(我接管了大量的遗留代码)会有大量内存泄漏和强引用,我不希望PCI敏感数据在我退出后很长时间仍保留在内存中“将
字符串设置为
null
”。将字符串设置为null是否会为字符串中的每个字符设置一个null终止字符

这里有一些到目前为止我所做的一些研究的链接,我想我正在寻找的可能是在我完成非托管内存后的写/重写:

TLDR:

  • 我知道我可以将
    字符串设置为
    null
    ,但我仍然不相信我的应用程序内存中没有仍然可以被恶意方引用的敏感数据

  • 您如何保证(通过代码/单元测试)字符串永远不能从内存中再次引用(即使是从恶意的第三方)

  • 抱歉,如果我有点偏执的话,我刚才在这个代码库中看到了这么多糟糕的内存管理(大部分来自一个深度嵌入的第三方框架)

    我了解垃圾收集的主要概念,关于如何一年一次 特定对象不再有引用它的指针,它是“垃圾” 收集”

    差不多。主要的一点是,在销毁对该对象的最后一次引用后,不会立即对该对象进行垃圾收集。在该对象处于挂起状态并等待启动垃圾收集过程之后

    这是否意味着它已释放,但其值仍可用于 有人用调试器/反汇编程序来读取(至少在此之前 地址是写给谁的

    是的。正如我前面提到的,释放的对象仍在内存中,并等待GC启动。因为垃圾收集是不确定的,所以您不知道垃圾收集器何时执行其工作。 此外,您仍然可以获得对此对象的引用(通过Finalize方法)

    我知道大多数对象(在中实现IDisposable接口的对象) C#您可以调用Dispose()方法并确信 内存再也不能被访问了。但是字符串呢

    此接口的主要用途是释放非托管资源。当托管对象不再使用时,垃圾收集器会自动释放分配给该对象的内存。 处置托管对象并不意味着该对象是释放的-处置仅更改该对象的内部状态(例如,它释放本机位图引用),但该对象保持不变-它消耗内存,仍然可以使用,您可以调用其方法,等等。只有GC从内存中移除对象。 因此,由于字符串是托管对象,它由GC释放

    如何保证(通过代码/单元测试)字符串不能 是否再次从内存中引用(即使是从恶意的第三方 党)


    在我看来,解决方案是使用dispose-like功能实现您自己的字符串包装器-例如,在您使用此包装器类的实例并且不再需要它之后,您可以调用Free()方法,并且您的实现将重写内存中基础字符串的值(在安全或不安全的上下文中)。但它需要精确的资源管理。此外,Finalize()方法应调用字符串重写,以确保在对象被GC-ed后内存归零。

    接受@barac340答案,因为这对于帮助我在找到解决方案时理解内存管理至关重要

  • 我只使用了
    SecureString
    ,并使用了一个同时发送 它通过加密通道输出,然后删除SecureString 过去了
  • 我使用
    封送
    类重写每个 字节表示从内存地址开始的
    SecureString
    的字节长度 非托管内存中的
    SecureString
  • 然后我处理掉它,为它释放出一堆空字符 垃圾收集。:)
  • 我想澄清的是,Xamarin.iOS上的一个已知问题是,
    SecureString
    的内存地址没有在secure string上加密,因此,即使内存被释放出来供GC按原样使用,它仍然可以通过内存检查以纯文本形式提供

    我没有创建自定义类,不是因为它不利于重用,我只是在本例中的一个位置使用它。我的大多数“未来”用例都需要在第一次“获取”后处理所述字符串“是
    SecureString
    的实际
    String
    值。因此,现在我只是将处理放在使用该字符串的函数中。特别是因为我已经在使用
    marshall
    读取
    字符串,所以在使用相同的方法后对其进行写入是有意义的

    如果需要自定义类,我将配音“ExtraSecureString”,
    我会这样做。

    我看到了这一点,我在阅读这些文档时看到的第一件事是。它看到了一段话,说它适合
    .Net Framework
    ,但
    Xamarin
    只使用
    .Net核心
    ,然后在运行时编译成
    iOS
    Android
    二进制文件