0

我有一个用户向其发布 XML 文件的 servlet。

我使用以下方法读取该文件:

String xml = request.getParameter("...");

现在说 xml 文档是 10KB,因为我创建了变量,所以xml我现在为该变量使用了 10KB 的内存,对吗?

现在我需要解析该 xml(使用 xerces),并在将其传递给 saxparsers 解析方法时将其转换为输入流(http://docs.oracle.com/javase/1.5.0/docs/api/ javax/xml/parsers/SAXParser.html)。

因此,如果我将字符串转换为流,是否会使我的内存使用量增加一倍?

需要对此进行一些澄清。

如果我在单步执行代码时将我的进程与 visualvm 或 jconsole 连接,我是否可以在单步执行调试器中的代码时查看是否使用了额外的内存?

我想确保我不会低效地执行此操作,因为此端点将受到重创。

4

5 回答 5

1

10,000 字节的文本通常会变成 20 KB。

当您处理文本时,您通常需要 2-10 倍以上的内存,因为您将使用该信息执行某些操作,例如创建数据结构。

这意味着您可能需要 200 KB。但是,鉴于在 PC 中这代表 1 美分的价值,我通常不会担心。如果您有一个资源严重受限的设备,我会考虑将处理转移到另一个设备,如服务器。

于 2012-05-16T19:59:09.000 回答
1

我认为您可能会在实际看到代码运行之前对其进行优化。JVM非常好并且可以快速恢复未使用的内存。

但是回答你的问题String xml = request.getParameter("...");并没有使内存加倍,它只是为指针分配了额外的 4 或 8 个字节(取决于 JVM 是否使用压缩指针)。

解析 xml 是不同的,SAX 解析器非常节省内存,所以它不会使用太多内存,我认为每个处理程序大约 20 个字节加上你拥有的任何实例变量......显然你可能会在其中生成任何额外的对象处理程序。

因此,您拥有的代码看起来就像它可以获得的内存效率一样高(当然取决于您的处理程序中的内容)。

除非您正在将该代码嵌入到设备中或每秒运行 100k 次,否则我建议您不要优化任何东西,除非您确定需要优化它。JVM 有一些疯狂的高级逻辑来优化代码,垃圾收集器可以非常快速地恢复短期对象。

于 2012-05-16T20:01:29.833 回答
1

如果用户可以将大量文件发布回您的 servlet,那么最好不要使用 getParameter() 方法并直接处理流 - Apache File Upload Library

这样您就可以在 InputStream 上使用 SAX 解析器(并且在处理之前不需要将整个文本加载到内存中)——就像您必须使用基于字符串的解决方案一样。

与 String xml = getParameter(...) 解决方案相比,这种方法扩展性很好,每个请求只需要少量内存。

于 2012-05-16T20:06:19.613 回答
0

您将编写如下代码:

saxParser.parse(new InputSource(new StringReader(xml));

您首先需要StringReader围绕xml. 这不会使您的内存使用量加倍,StringReader类只是包装xml变量并在请求时逐个字符地返回它。

InputSource甚至更薄 - 它只是简单地包装提供ReaderInputStream。简而言之:不,您String不会被复制,您的实现非常好。

于 2012-05-16T20:00:13.107 回答
0

不,你不会得到字符串的 2 个副本,从而使你的内存加倍。其他东西可能会使内存加倍,但字符串本身不会被复制。是的,您应该连接 visualVm 和 jconsole 以查看内存和线程处理会发生什么。

于 2012-05-16T20:01:09.730 回答