.net 应用程序泄漏字符串?

.net 应用程序泄漏字符串?,.net,string,memory-leaks,.net,String,Memory Leaks,我的.net应用程序执行了一些繁重的字符串加载/操作,不幸的是,内存消耗不断增加,当使用探查器查看它时,我看到许多未发布的字符串实例。现在,在某个时间点,我确实需要所有具有这些字符串字段的对象,但一旦完成,我可以去掉其中的一半,然后我Dispose()并将实例设置为null,但垃圾回收器不会拾取该值。。它们会留在记忆中(即使在处理后半小时后) 现在,我如何正确地摆脱不需要的字符串/对象实例以释放它们 它们不再被引用(afaik),但例如aspose的内存分析器说它们到gc根的距离是“3” 更新:

我的.net应用程序执行了一些繁重的字符串加载/操作,不幸的是,内存消耗不断增加,当使用探查器查看它时,我看到许多未发布的字符串实例。现在,在某个时间点,我确实需要所有具有这些字符串字段的对象,但一旦完成,我可以去掉其中的一半,然后我Dispose()并将实例设置为null,但垃圾回收器不会拾取该值。。它们会留在记忆中(即使在处理后半小时后)

现在,我如何正确地摆脱不需要的字符串/对象实例以释放它们

它们不再被引用(afaik),但例如aspose的内存分析器说它们到gc根的距离是“3”

更新:原始字符串来自互操作实例。有没有可能是这些导致了泄漏

如。。分配

myClass.StringProperty = interopInstance.Description.Text;

。。my.StringProperty是否仍有对该互操作的引用,因此“泄漏”/保持互操作状态未收集&未正确释放/取消签名?

当包含该字段的类仍将被使用时,将私有字段设置为
null
可能很有用。它将允许收集引用的对象。但是,当该私有字段本身的实例未被引用时,它引用的对象也将被引用。换句话说,在一个很快未被引用的对象上清空私有字段是没有用的

我认为您没有应用程序泄漏。也许您正在创建存储在大对象堆(LOH)中的字符串。当大于或等于85000字节(包含42492个或更多字符)时,对象存储在LOH中。LOH仅在发生完全垃圾收集(gen 2)时收集。因此,由于您似乎没有任何
OutOfMemoryExceptions
,因此我认为没有泄漏。您的应用程序不会耗尽内存,GC也不会收集Gen2

您可以通过调用
GC.Collect()
来检查这一点。这将删除所有未使用的大型对象


因此,虽然应用程序中可能没有泄漏,但内存占用可能会过大。尤其是当您编写的桌面应用程序不是唯一需要内存的应用程序时。除此之外,大量内存也可能导致性能问题,因为GC必须更频繁地运行

也许可以用更少内存的方式重构代码。例如,使用
StringBuilder
对象(如果您还没有这样做的话)。或者甚至可以缓存池中的
StringBuilder
对象,并重用它们,而不是创建新对象。尤其是在使用从池中获取的实例时设置属性。这可能特别有用,因为LOH容易变得支离破碎,这可能导致出现
outofmemoryException
。这只是32位系统上的一个问题,因为64位系统几乎有无限的虚拟地址空间。64位在未来几年将越来越成为主流,我相信微软还没有投资解决32位CLR版本的这个问题,正因为如此

更新:
在互操作的情况下,字符串被序列化和反序列化。一个字符串作为字节数组发送,所以一般来说,保留引用不会改变它。但是,每次从interop获取字符串时,都会创建一个新的字节数组,并且在.NET中,字节[]会复制到字符串中。这将使使用的内存量加倍。

当包含该字段的类仍将被使用时,将专用字段设置为
null
可能会很有用。它将允许收集引用的对象。但是,当该私有字段本身的实例未被引用时,它引用的对象也将被引用。换句话说,在一个很快未被引用的对象上清空私有字段是没有用的

我认为您没有应用程序泄漏。也许您正在创建存储在大对象堆(LOH)中的字符串。当大于或等于85000字节(包含42492个或更多字符)时,对象存储在LOH中。LOH仅在发生完全垃圾收集(gen 2)时收集。因此,由于您似乎没有任何
OutOfMemoryExceptions
,因此我认为没有泄漏。您的应用程序不会耗尽内存,GC也不会收集Gen2

您可以通过调用
GC.Collect()
来检查这一点。这将删除所有未使用的大型对象


因此,虽然应用程序中可能没有泄漏,但内存占用可能会过大。尤其是当您编写的桌面应用程序不是唯一需要内存的应用程序时。除此之外,大量内存也可能导致性能问题,因为GC必须更频繁地运行

也许可以用更少内存的方式重构代码。例如,使用
StringBuilder
对象(如果您还没有这样做的话)。或者甚至可以缓存池中的
StringBuilder
对象,并重用它们,而不是创建新对象。尤其是在使用从池中获取的实例时设置属性。这可能特别有用,因为LOH容易变得支离破碎,这可能导致出现
outofmemoryException
。这只是32位系统上的一个问题,因为64位系统几乎有无限的虚拟地址空间。64位在未来几年将越来越成为主流,我相信微软还没有投资解决32位CLR版本的这个问题,正因为如此

更新: 在互操作的情况下,字符串被序列化和反序列化。一个字符串作为字节数组发送,所以一般来说,保留引用不会改变它。但是,每次从互操作获取字符串时