C# 从内存中删除文件流
听起来像是重复的,但我找不到任何相关的解决方案,我正在开发一个桌面应用程序,用户可以通过HTTP将文件上传到服务器。这个应用程序运行得很好,但是它占用了太多的内存,因为我必须打开文件的C# 从内存中删除文件流,c#,memory-management,filestream,C#,Memory Management,Filestream,听起来像是重复的,但我找不到任何相关的解决方案,我正在开发一个桌面应用程序,用户可以通过HTTP将文件上传到服务器。这个应用程序运行得很好,但是它占用了太多的内存,因为我必须打开文件的FileStream,才能上传它 我尝试使用(var fs=File.Open(path,mode)){}调用.Dispose()和,但显然它并没有释放内存,只是删除对象 我还尝试了: GC.Collect(); GC.WaitForPendingFinalizers(); 这是可行的,但我已经读到,调用垃圾收
FileStream
,才能上传它
我尝试使用(var fs=File.Open(path,mode)){}调用.Dispose()
和,但显然它并没有释放内存,只是删除对象
我还尝试了:
GC.Collect();
GC.WaitForPendingFinalizers();
这是可行的,但我已经读到,调用垃圾收集器不是一个好的做法,可能会影响应用程序的性能。我想做的很简单
我看了文件
我上传文件
我(从内存中)删除该文件
我该怎么做呢?请确保Close()
完成FileStream
一种常见的方法是使用使用,而不是自己管理:
using(var input = File.Open(filename))
{
// use input to read/upload/etc
} // input gets closed (via IDisposable.Dispose() here)
如果文件流正确关闭,GC将自动从内存中清除文件数据
如果您的目标是减少内存使用,则可能需要另一种方法。与将整个文件读入内存并上传不同,您可能希望以块的形式读取并上传(流式传输结果)或类似的内容 确保完成Close()
FileStream
一种常见的方法是使用使用,而不是自己管理:
using(var input = File.Open(filename))
{
// use input to read/upload/etc
} // input gets closed (via IDisposable.Dispose() here)
如果文件流正确关闭,GC将自动从内存中清除文件数据
如果您的目标是减少内存使用,则可能需要另一种方法。与将整个文件读入内存并上传不同,您可能希望以块的形式读取并上传(流式传输结果)或类似的内容 “但是它占用了太多的内存”。你对此有何证据?症状是什么?你只是有不同于GC的观点吗?用户的上传限制是512mb,所以我尝试上传一个大文件,当我查看任务管理器时,使用的内存会增加,并且在使用GC时保持不变,但内存会从530MB(整个文件大小+使用的内存)减少到20MB,它的工作原理和我预期的一样,但我怀疑是否使用它或not@neo您已经通过调用GC.Collect()
证明了当垃圾收集发生时,内存将被释放。因此,现在您知道,一旦满足垃圾收集的条件,内存将被释放(注意,这并不经常发生,通常只有在内存不足时才会发生),很可能是上载代码的问题,如果你真的遇到了内存问题,那么你可能需要查看文件流,而不是将其完全缓冲到内存中。查看MemoryMappedfile及其ViewAccessor。您可以让一个线程读取512kb块,通过移动访问器上传并读取文件中的下一个块。最多几兆字节,“但它占用了太多内存”。你对此有何证据?症状是什么?你只是有不同于GC的观点吗?用户的上传限制是512mb,所以我尝试上传一个大文件,当我查看任务管理器时,使用的内存会增加,并且在使用GC时保持不变,但内存会从530MB(整个文件大小+使用的内存)减少到20MB,它的工作原理和我预期的一样,但我怀疑是否使用它或not@neo您已经通过调用GC.Collect()
证明了当垃圾收集发生时,内存将被释放。因此,现在您知道,一旦满足垃圾收集的条件,内存将被释放(注意,这并不经常发生,通常只有在内存不足时才会发生),很可能是上载代码的问题,如果你真的遇到了内存问题,那么你可能需要查看文件流,而不是将其完全缓冲到内存中。查看MemoryMappedfile及其ViewAccessor。您可以让一个线程读取512kb块,通过移动访问器上传并读取文件中的下一个块。最多几兆字节。@neo请注意,垃圾收集不是即时的,也不像您想象的那样频繁。“垃圾收集条件”下的更多信息@Neo您发送的文件有多大或多少?如果使用上述方法,垃圾收集器将在需要时释放内存。@Neo您可能会误解答案,代码显示了一种通用方法,它完全取代了Close()
@Neo Yes,但您需要调用Close(),或显式调用Dispose(),或者像我演示的那样使用包装。@alexw感谢分享链接,好吧,我想我会把这项工作留给垃圾收集器,或者遵循Reed的选择。@neo请注意垃圾收集不是即时的,也不像你想象的那样频繁。“垃圾收集条件”下的更多信息@Neo您发送的文件有多大或多少?如果使用上述方法,垃圾收集器将在需要时释放内存。@Neo您可能会误解答案,代码显示了一种通用方法,它完全取代了Close()
@Neo Yes,但您需要调用Close(),或显式调用Dispose(),或者像我演示的那样用using包装。@alexw感谢分享链接,我想我会把这项工作交给垃圾收集器,或者按照Reed的选择去做。。