`

Javamail读取邮件列表出现OutOfMemery

阅读更多

用Javamail解析多个邮件的时候,如果个别邮件的附件过大,就会造成OutOfMemery的情况,如下

 

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
	at java.util.Arrays.copyOf(Arrays.java:2786)
	at java.io.ByteArrayOutputStream.write(ByteArrayOutputStream.java:71)
	at com.sun.mail.pop3.Protocol.multilineCommand(Protocol.java:362)
	at com.sun.mail.pop3.Protocol.retr(Protocol.java:237)
	at com.sun.mail.pop3.POP3Message.getContentStream(POP3Message.java:115)
	at javax.mail.internet.MimePartDataSource.getInputStream(MimePartDataSource.java:60)
	at javax.mail.internet.MimeMultipart.parse(MimeMultipart.java:259)
	at javax.mail.internet.MimeMultipart.getCount(MimeMultipart.java:159)
	at com.gdcn.mail.util.Pop3Util.hasAttachment(Pop3Util.java:1148)
	at com.gdcn.mail.util.Pop3Util.analysisMessage(Pop3Util.java:774)
	at com.gdcn.mail.util.Pop3Util.getMessages(Pop3Util.java:561)
	at com.gdcn.mail.util.Pop3Util.main(Pop3Util.java:1338)
 

原因是JavaMail会将这些Messages读入内存,由于这些邮件包含了附件等等,所以会造成这样的结果。

 

网上很多都说增加JVM或者Tomcat等的内存,但是这样仍然不能达到预期的效果。或来查阅了相关的文档和网上的结果,发现了解决这个问题的方法,我们只需要在解析完邮件之后增加这句

 

((POP3Message) message).invalidate(true);

 

sun有这样的解析

http://java.sun.com/products/javamail/javadocs/com/sun/mail/pop3/POP3Message.html

invalidate

public void invalidate
(boolean invalidateHeaders)
Invalidate the cache of content for this message object, causing it to be fetched again from the server the next time it is needed. If invalidateHeaders is true, invalidate the headers as well.

 

Parameters:
invalidateHeaders - invalidate the headers as well?

 

这样就很好地将原来读取的message从cache里面擦除了

分享到:
评论
4 楼 Ben.Sin 2011-10-01  
liupeng_10408 写道
博主,你好!我开发的是android版邮件系统。
只写了如下几句,就报错了:
Multipart mp = (Multipart) msg.getContent();
int count = mp.getCount(); //这行报错:outofmemoryerror

你说的那句难道要写在报错这句的前面吗?



android的情况我不知道,或者确实需要更大的内存,因为原来的我在PC上开发。
邮件解析的时候通常要下载整个邮件,有的时候附件太大了就会很慢或者很可能引起outofmemer. 所以当我们轮询邮件的时候要执行释放
((POP3Message) messagei).invalidate(true); 
内部如何实现我并没有太深入研究,这个项目也成了历史了
3 楼 liupeng_10408 2011-09-24  
博主,你好!我开发的是android版邮件系统。
只写了如下几句,就报错了:
Multipart mp = (Multipart) msg.getContent();
int count = mp.getCount(); //这行报错:outofmemoryerror

你说的那句难道要写在报错这句的前面吗?
2 楼 Ben.Sin 2010-03-04  
ccxw1983 写道
我添了这句代码,还是报错,代码片段如下:
messages = inbox.getMessages(i);
inbox.fetch(messages, profile);
messagei = messages[0];
((POP3Message) messagei).invalidate(true); 
不知你是如何设置的,请赐教!
我的附件有32.7M。



不好意思,一直在忙,没时间来打理,不知道你找到答案了没有?

我是采用Folder.open()的方式访问的,大致意思如下

Session session = this.getSession(pop3Server, mailAddress, password, port);

Store store = this.getStore(session, protocol);
// Connect to mail server
store.connect();
Folder folder = store.getFolder("INBOX");
if (folder.exists()) {
   folder.open(Folder.READ_ONLY);
   messages = folder.getMessages(messageIds);

   for (Message message : messages) {
      // 解析邮件部分省略。。。

      // 释放邮件
      ((POP3Message) message).invalidate(true);
   }
}



1 楼 ccxw1983 2009-12-31  
我添了这句代码,还是报错,代码片段如下:
messages = inbox.getMessages(i);
inbox.fetch(messages, profile);
messagei = messages[0];
((POP3Message) messagei).invalidate(true); 
不知你是如何设置的,请赐教!
我的附件有32.7M。

相关推荐

Global site tag (gtag.js) - Google Analytics