我正在向WebSphere的response.getOutputStream()写一个大的响应(数百Mb)。 Web Sphere似乎始终将整个输出流数据存储在某些内部内存缓冲区中,然后再将其提供给客户端。因此,我的服务处理(生成数据)在几秒钟内完成,而浏览器可能仍在下载半小时。在此期间,整个响应仍保留在内存中。
是否可以避免这种缓冲? 我更喜欢等待输出流的servlet线程,而不是浪费Gbs的内存。
My Web Sphere版本为8.5.0。
我已经尝试过设置内容长度和分块响应 - 它们都是一样的,仍然在缓冲。 我的TCP传输链设置是默认的32 kb响应缓冲区,但它会以某种方式被忽略。
答案 0 :(得分:5)
同时,在WAS网络容器custom properties中找到答案。
默认情况下,Web容器使用异步写入将响应数据写入块中,直到响应缓冲区大小。对于大于响应缓冲区大小的较大响应,Web容器继续将响应数据缓冲到内存中,同时等待异步写入响应数据块以完成。此过程可能导致在内存中保留大部分响应,这可能导致高内存使用并可能导致内存不足错误。当服务器同时处理比Web容器定义的线程更多的请求时,也可能发生应用程序服务器挂起。
如果com.ibm.ws.webcontainer.channelwritetype属性设置为sync,则使用同步写入,否则默认使用异步写入。通过同步写入,响应数据以最多为responsebuffersize的值的块同步写入,并且在等待响应数据块的同步写入完成时,没有响应数据被缓冲到存储器中。因此,内存中保存的近似最大响应数据量等于responsebuffersize乘以Web容器线程数。 Web容器可以同时处理的最大请求数受Web容器线程数的限制。其他请求排队等待正在处理的请求。
responsebuffersize Web容器定制属性定义Web容器在单个块中写入的最大响应数据量,默认为32k。因此,它用于更改Web容器发送完整响应数据所需的写入次数。但是,如果应用程序刷新响应数据,则无论响应是否有效,都会立即写入Web容器保存的任何响应数据。
使用以下名称 - 值对使用同步写入来写入数据块。
com.ibm.ws.webcontainer.channelwritetype async
答案 1 :(得分:1)
您确定Websphere将此数据存储在内部内存缓冲区中吗? Websphere通道输出缓冲区一次只能容纳32K数据。所以剩余的数据可能由你的servlet保存,因为你已经生成了一些存储在堆中并由你的代码引用的大数据。
查看您的代码并查看代码所引用的数据,如果您想知道存储在内存中的内容以及将其保持活动状态,请拍摄堆的快照(堆转储)。