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か?


更新:ご親切にありがとうございます。ByteArrayDataSource の代わりに FileDataSource を使用しています。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

問題は、メッセージの作成中にファイル全体をメモリに保存しようとしていることですが、これは通常は必要ありません。実際のファイルを添付する場合は、データをメモリに保持するのではなくストリーミングできるため、 a のjavax.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.


したがって、あなたの質問に答えるには、(少なくとも) 2 つのオプションがあります。

  1. FileDataSourceこのSO 回答で like を使用します
  2. プログラムにより多くのメモリを与えます (この場合、おそらく良い解決策ではありません..)
于 2012-07-02T09:19:59.713 に答える
-1

私は同じ問題に直面していました。ただし、同時に複数のメールを送信中。ログに 2 つのエラーが発生します。

1. OutOfMemoryError: Java ヒープ領域

2. 最大接続数を超えました

wrapper.conf ファイルの 2 つのパラメーターを変更しました。

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

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

サーバーの再起動後、エラーはなくなり、メールの送受信が機能しています。

于 2015-07-22T07:40:24.500 に答える