c# - 在缓冲模式下使用 WCF 发送大字节 [] 时内存分配失败
问题描述
我想WCF
用于在客户端和服务器之间传输文件。我读了很多文章,有些人Stream
为此目的使用模式。但由于它的限制,我决定使用缓冲模式创建服务。例如考虑这个:
[OperationContract]
void UploadFile(Guid systemKey, string fileName, byte[] fileContent, string userName);
服务器网络配置:
...
<system.web>
<compilation debug="true" targetFramework="4.6" />
<httpRuntime targetFramework="4.6" maxRequestLength="2147483647" executionTimeout="7200"/>
</system.web>
....
<bindings>
<basicHttpBinding>
<binding name="myBasicBinding" maxBufferSize="2147483647"
maxReceivedMessageSize="2147483647"
closeTimeout="01:50:00"
openTimeout="01:50:00"
sendTimeout="01:50:00"
receiveTimeout="01:50:00"
messageEncoding="Mtom">
<readerQuotas maxDepth="128" maxStringContentLength="8388608" maxArrayLength="2147483647" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
</binding>
</basicHttpBinding>
</bindings>
....
<system.webServer>
<security>
<requestFiltering>
<requestLimits maxAllowedContentLength="4294967295"/>
</requestFiltering>
</security>
<modules runAllManagedModulesForAllRequests="true"/>
<directoryBrowse enabled="true"/>
</system.webServer>
和客户端配置:
<system.web>
<compilation debug="true" targetFramework="4.6"/>
<httpRuntime targetFramework="4.6" maxRequestLength="2147483647" executionTimeout="7200"/>
</system.web>
...
<system.webServer>
<security>
<requestFiltering>
<requestLimits maxAllowedContentLength="4294967295"/>
</requestFiltering>
</security>
</system.webServer>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="basicEndpoint"
maxBufferSize="2147483647"
maxReceivedMessageSize="2147483647"
closeTimeout="01:50:00"
openTimeout="01:50:00"
sendTimeout="01:50:00"
receiveTimeout="01:50:00"
messageEncoding="Mtom">
<readerQuotas maxDepth="128" maxStringContentLength="8388608" maxArrayLength="2147483647" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost/fts.svc" binding="basicHttpBinding" bindingConfiguration="basicEndpoint" contract="ServiceReference1.Ifts" name="basicEndpoint"/>
</client>
</system.serviceModel>
我可以上传400MB
文件,但是当文件大小为500MB
或以上时,我收到此错误:
System.InsufficientMemoryException HResult=0x8013153D 消息=未能分配 1073741824 字节的托管内存缓冲区。可用内存量可能很低。源=mscorlib
内部异常 1:OutOfMemoryException:引发了“System.OutOfMemoryException”类型的异常。\
我想我为2GB
数据设置了值,但它在500MB
.
谢谢
此代码在本地运行,我有16GB
RAM。问题出在哪里,我应该更改什么值来上传硬文件?
谢谢
解决方案
我记得我正在处理一个大文件传输,我使用buffered
模式传输但不是最好的解决方案,因为过了一段时间我遇到了一些关于内存泄漏或相关内存的异常,我将其更改为transferMode="Streamed"
并且一切正常,由buffered
模式意味着消息的全部内容在发送之前或接收之后都存在于内存中。虽然这对于大多数情况来说是一个很好的策略,并且对于数字签名和可靠传递等消息传递功能是必需的,但大消息可能会耗尽系统的资源。
看看这里。
为了避免一直创建新缓冲区,WCF 使用BufferManager重用缓冲区,达到 指定的限制maxBufferPoolSize
,
buffers
创建和销毁的成本很高。您可以使用BufferManager类来管理缓冲池。
您可以尝试增加maxBufferPoolSize
以查看是否可以减少内存使用量。我强烈建议不要将其增加到最大值,因为我认为池中的缓冲区在应用程序域得到回收之前永远不会释放。一段时间的高流量可能会导致大量内存被使用并且永远不会被释放。
所以我建议你使用streamed
模式传输大文件。
要拆分文件并使用以下链接的大型流,可能会对您有所帮助:
一个流中的多个文件,自定义流
将大文件返回为拆分 zip 文件、流或字节数组 WCF 的最佳方式
它也可以帮助你
推荐阅读
- excel - Worksheet.Calculate_Cell 更改复制相邻单元格文本
- r - 在计算 R 中基于 95% 似然的置信区间时,我想用 gamma 函数替换指数函数
- fontforge - 如何为多个字符使用相同的字形?
- python - GridSearchCV 是否总能提高分类或回归模型的模型准确性?
- python - 我不断收到此错误,但我不知道为什么(TypeError: __init__() 需要 2 个位置参数,但给出了 3 个)
- python - 如何向 Flask rest API 添加基本授权?
- vba - Word 中的 VBA 代码,用于检查当前宏是否为最新版本
- python - 即时将数据写入 CSV 并使用快速 api 下载文件
- dialog - 任何人都可以告诉这个对话框有什么问题吗?
- angular10 - Angular 10 升级错误:TS2300:重复标识符“IteratorResult”