2

OutOfMemoryError: Java Heap Space当我尝试附加一个大附件时,我遇到了一个。当发送带有一些大文件(比如 50M)的电子邮件时,将引发错误。

代码是这样的:

//add attaches
if (vo.getAttaches() != null) {
    InputStream iStream = null;
    ByteArrayDataSource bdSource = null;
    String filename = null;

    for (int i = 0; i < vo.getAttaches().length; i++) {
         iStream = new FileInputStream(vo.getAttaches()[i]);
         bdSource = new ByteArrayDataSource(iStream, null);
         filename = vo.getAttachesFileName()[i];
         email.attach(bdSource, MimeUtility.encodeText(filename), filename);
    }
}

bdSource = new ByteArrayDataSource(iStream, null)抛出了上面的异常。我读过“使用 java 邮件内存不足”,但我不明白。如何上传大附件?如果我定义一个缓冲区byte[1024],那么如何编码email.attach()?缓冲区中的所有数据都应该使用相同的filename吗?


更新:谢谢你的好意。我使用 FileDataSource 而不是 ByteArrayDataSource,看来我的 send() 函数没有异常。但我仍然无法发送带有大附件的电子邮件。apache james收到此错误:

    java.lang.OutOfMemoryError: Java heap space
    at java.util.Arrays.copyOf(Arrays.java:2786)
    at java.io.ByteArrayOutputStream.toByteArray(ByteArrayOutputStream.java:133)
    at com.sun.mail.util.ASCIIUtility.getBytes(ASCIIUtility.java:261)
    at javax.mail.internet.MimeMessage.parse(MimeMessage.java:338)
    at org.apache.james.core.MimeMessageWrapper.parse(MimeMessageWrapper.java:477)
    at org.apache.james.core.MimeMessageWrapper.loadMessage(MimeMessageWrapper.java:205)
    at org.apache.james.core.MimeMessageWrapper.checkModifyHeaders(MimeMessageWrapper.java:414)
    at org.apache.james.core.MimeMessageWrapper.setHeader(MimeMessageWrapper.java:426)
    at org.apache.james.core.MimeMessageCopyOnWriteProxy.setHeader(MimeMessageCopyOnWriteProxy.java:652)
    at org.apache.james.transport.mailets.UsersRepositoryAliasingForwarding.service(UsersRepositoryAliasingForwarding.java:101)
    at org.apache.james.transport.mailets.LocalDelivery.service(LocalDelivery.java:64)
    at org.apache.james.transport.LinearProcessor.service(LinearProcessor.java:424)
    at org.apache.james.transport.JamesSpoolManager.process(JamesSpoolManager.java:405)
    at org.apache.james.transport.JamesSpoolManager.run(JamesSpoolManager.java:309)
    at java.lang.Thread.run(Thread.java:619)
03/07/12 13:08:33 ERROR spoolmanager: An error occurred processing Mail1341292071375-0 through transport
03/07/12 13:08:33 ERROR spoolmanager: Result was error
03/07/12 13:08:33 ERROR spoolmanager: Exception in processor <error>
java.lang.OutOfMemoryError: Java heap space
    at java.util.Arrays.copyOf(Arrays.java:2786)
    at java.io.ByteArrayOutputStream.write(ByteArrayOutputStream.java:94)
    at org.apache.james.core.MimeMessageUtil.copyStream(MimeMessageUtil.java:168)
    at org.apache.james.core.MimeMessageWrapper.writeTo(MimeMessageWrapper.java:276)
    at org.apache.james.core.MimeMessageUtil.writeTo(MimeMessageUtil.java:66)
    at org.apache.james.core.MimeMessageUtil.writeTo(MimeMessageUtil.java:50)
    at org.apache.james.mailrepository.MessageInputStream.writeStream(MessageInputStream.java:131)
    at org.apache.james.mailrepository.MessageInputStream.<init>(MessageInputStream.java:101)
    at org.apache.james.mailrepository.JDBCMailRepository.store(JDBCMailRepository.java:718)
    at org.apache.james.transport.mailets.ToRepository.service(ToRepository.java:98)
    at org.apache.james.transport.LinearProcessor.service(LinearProcessor.java:424)
    at org.apache.james.transport.JamesSpoolManager.process(JamesSpoolManager.java:405)
    at org.apache.james.transport.JamesSpoolManager.run(JamesSpoolManager.java:309)
    at java.lang.Thread.run(Thread.java:619)
03/07/12 13:08:33 ERROR spoolmanager: An error occurred processing Mail1341292071375-0 through error
03/07/12 13:08:33 ERROR spoolmanager: Result was ghost
4

3 回答 3

4

问题是您在撰写消息时试图将整个文件存储在内存中,这实际上通常不是必需的。如果您要附加真实文件,那么最好使用 ajavax.activation.FileDataSource而不是 a javax.mail.util.ByteArrayDataSource(两者都实现DataSource接口),因为它可以允许数据流式传输而不是保存在内存中。

于 2012-07-02T09:19:14.650 回答
2

对于您的更新:在 2010年 12 月 30 日的同一线程中转换为“邮件格式(ascii)”时,似乎一个旧的(?)变体将整个文件JamesSpoolManager入内存,问题似乎已解决。


ByteArrayDataSource将从提供的输入流中读取完整的输入,请参阅 javadoc:

使用来自指定 InputStream 的数据和指定的 MIME 类型创建一个 ByteArrayDataSource。InputStream 被完全读取,数据存储在一个字节数组中。

因此,如果要读取的文件“大于”您的堆大小(JVM 限制),它将抛出OutOfMemoryException.


因此,要回答您的问题,您有(至少)两种选择:

  1. FileDataSource在这个SO 答案中使用类似
  2. 给你的程序更多的内存(在这种情况下可能不是一个好的解决方案..)
于 2012-07-02T09:19:59.713 回答
-1

我面临同样的问题。但是,同时在多封电子邮件中。这会导致日志中出现两个错误。

1. OutOfMemoryError: Java 堆空间

2. 超出最大连接数

我在 wrapper.conf 文件中更改了两个参数。

#wrapper.java.initmemory=16
 wrapper.java.initmemory=32

#wrapper.java.maxmemory=64
wrapper.java.maxmemory=128

重新启动服务器后,错误消失并且邮件发送接收正在工作。

于 2015-07-22T07:40:24.500 回答