Unludo 是正确的,您需要使用 STAX 来保持此过程尽可能高效 - 实际上有 5 种不同的方式可以在 Java 中解析 XML,我在这里概述了它们以及优缺点。
任何将整个内容保存在 ram(DOM 或 XPath)中的东西都会占用大量内存。SAX 要好得多,但它仍然会在遇到元素时解析出元素并将它们交给您的处理程序实现,而 STAX 在您请求之前不会解析流中的任何内容;它只会向您发出事件,让您知道它在看什么。
话虽如此,我创建了基于 STAX 的SJXP 解析库,以提供具有 XPath 易用性的 STAX 性能。
您从字面上定义您感兴趣的文件中的路径,例如:
/message/data -- represents the <message><data>[STUFF HERE]</data></message> path
然后将所有路径(它们基本上是规则)提供给解析器,然后给它您要解析的文件,它会为您完成所有肮脏的工作,只有在找到您要求的内容时才调用您的代码。
该实现非常高效(我不是在开玩笑,我花了几天时间对其进行分析以获取低于基本 STAX 类的实现开销,因此它不会增加可测量的开销)并且超级易于使用。
注意您说每条消息附带的 byte[] 是“单独的文件”,我不确定您在 XML Parsing 上下文中的意思;我想我们中的一些人可能认为您的二进制数据是在您的 XML 消息中进行 base64 编码的,如果不是这种情况,并且您有辅助的数据有效负载,每条消息都通过网络传输,那么您将要做什么保持低内存使用率是将数据(一次一个块)从线路直接传输到数据库。
如果您的数据库不允许流式一次插入一个段的值并且需要整个 byte[] blob,那么只需将该 byte[] 从网络中取出并尽快放入 DB 以保持较低的内存使用率;如果这些确实是每个 1MB 的原始数据,那么这很可能是什么让你的堆爆炸,特别是如果有很多同时连接的情况。
如果您想分享有关您的 impl 的更多数据,我相信我们可以提供建议。