java mail API使用流媒体吗?我在哪里可以获得源代码来确认这一点。 我也尝试使用原始和非原始模式发送邮件。 在原始模式下,我可以将输入流传递给MimeMessage构造函数:[/ b]
new MimeMessage(session, doc.getBodyInputStream());
在非原始模式下,我必须执行以下操作
由于可以有任何mime类型,因此我必须使用DataHandler
和DataSource
。由于DataSource
接口契约表示每次调用getInputStream()
时都提供新的inputStream,我们需要将数据保存在byte[]
中,这将为大尺寸或文档抛出OOM有没有办法避免这个?
MimeMessage msg = new MimeMessage(session);
byte[] bArr = doc.getBody();
ByteArrayInputStream ins = new ByteArrayInputStream(
bArr != null && bArr.length > 0 ? bArr : "".getBytes());
msg.setDataHandler(new DataHandler( new ByteArrayDataSource(ins, mimeType)));
答案 0 :(得分:1)
如果您只处理一封邮件,或者在处理(和缓存!)多封邮件后获得OOM,是否会出现问题?
增加堆大小是一个选项,但是如果它只是增加了下一个OOM受到伤害的时间,那么你会考虑将原始字节数组保留在内存中的替代方法。
你应该使用ByteArrayDataSource(byte[] bArr, String type)
构造函数,这样可以防止复制内存中的完整字节数组,因为bArr
只是存储在DataSource中。另一个构造函数以一个8k字节的数组开始,每次需要更多空间时它的大小加倍 - 这会浪费大量内存并可能是导致问题的原因。 (source)
答案 1 :(得分:0)
关于OOM,一般来说你的邮件不应该大于10MB,而字节数组中的邮件不应该超过10MB。
这是一个理论问题吗?或者你真的看到了这种情况吗?
如果您看到它发生,那么增加堆大小,因为上面的代码看起来或多或少是正确的。
答案 2 :(得分:0)
是否可以将主体转储到(临时)文件,让转储的bArr超出范围(或设置为null)然后使用FileDataSource?