1

我与部署在 JBoss-4.2.3.GA 下的基于 Spring MVC 的应用程序有一个交易,并想阐明 servlet 输入/输出流如何与巨大的请求/响应主体一起工作。我对此很烦恼,因为不想将整个请求/响应保留在内存中,直到调用完全完成。

如何准确检测 JBoss 传递给 servlet 的输入/输出流实现?或者我可以在某种规范中调查它的行为?

感谢您提供有关它的任何有用信息。

4

1 回答 1

1

默认情况下,servlet API 不会将整个请求和响应主体保存在内存中。它实际上是您自己的处理/解析代码。

至于请求体,在处理它时,你不应该把整个请求体放在一个byte[]. a 的每个字节都会byte[]消耗 Java 内存的一个字节。您应该尝试(重新)编写代码,使其永远不会将整个正文保存在内存中。例如逐行或逐缓冲区处理它和/或立即将其流式传输到OutputStream.

例如,当身体是基于字符的:

BufferedReader reader = new BufferedReader(new InputStreamReader(request.getInputStream(), "UTF-8"));
PrintWriter writer = new PrintWriter(new OutputStreamWriter(someOutputStream, "UTF-8"));

for (String line; (line = reader.readLine()) != null;) {
    processIfNecessary(line);
    writer.writeln(line);
}

或者当正文是基于字节的:

BufferedInputStream input = new BufferedInputStream(request.getInputStream());
BufferedOutputStream output = new BufferedOutputStream(someOutputStream);
byte[] buffer = new byte[1024]; // 1KB buffer.

for (int length; (length = input.read(buffer)) > 0;) {
    processIfNecessary(buffer);
    output.write(buffer, 0, length);
}

至于响应体,它将一直保存在内存中,直到缓冲区大小。超出缓冲区大小的任何内容都将被刷新。默认缓冲区大小通常为 2KB。这可以在 appserver 级别和通过ServletResponse#setBufferSize(). 当您将缓冲区大小设置得太高时,它将吞噬内存。

于 2011-03-31T18:56:32.503 回答