我何时将内存使用量增加一倍?

时间:2012-05-16 19:51:04

标签: java servlets jvm jetty

我有一个用户将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连接我的进程,在单步执行代码时,我可以看到在使用调试器中的代码时是否正在使用额外的内存吗?

我想确保我不会效率低下,因为这个端点会受到重创。

5 个答案:

答案 0 :(得分:1)

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

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

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

答案 1 :(得分:1)

我认为您可能在实际看到它运行之前优化了代码。 JVM 非常良好且快速地恢复未使用的内存。

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

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

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

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

答案 2 :(得分:1)

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

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

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

答案 3 :(得分:0)

你将这样编码:

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

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

InputSource甚至更薄 - 只需提供ReaderInputStream。所以简而言之:不,你的String不会被复制,你的实现非常好。

答案 4 :(得分:0)

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