2009-09-23 41 views
3

我正在运行使用Javamail的服务器。它有一个带有IMAP IDLE的计数监听器,这样当有新邮件进来时,就会执行某些代码。新消息的列表作为参数提供给我的监听器。我读取了它的信息并完成它。一切都很好,除了我的服务器泄漏了大量的内存!我做了一个堆转储,发现类[Lcom.sun.mail.imap.IMAPMessage正在使用大量内存。看起来,一个IMAPMessage数组被对象com.sun.mail.imap.MessageCache引用。如何强制Javamail清除其消息缓存?

有缓存吗?我不需要再次访问这些消息,除非它第一次出现。我如何强制缓存清除?我怎样才能阻止javamail泄漏?

回答

1

按照docs,你PAS一个布尔值,表明删除的邮件应予以删除:

message.setFlag(Flags.Flag.DELETED, true); 
folder.close(aBoolean); 
store.close(); 
+0

这不是清除/清空Javamail缓存的答案。 – GreenKiwi 2012-02-08 21:11:30

1

我发现了JavaMail论坛 How to force Javamail to clear its message cache?

这个参考

然后做了一些挖掘。虽然我还没有找到一种方法来删除或缩小“缓存”,但我发现缓存的最大部分是消息的标题。 IMAPMessage中有两个头部副本,一个是它的内部MIMEMessage,另一个是MIMEMessage。现在,当您想清除这些信息时会遇到麻烦,因为它们只允许您访问清除IMAPMessage中的信息。 MIMEMessage中的标题不能被清除。此外,他们不能被删除。下面是从InternetHeaders.remove(string)的代码

/** 
* Remove all header entries that match the given name 
* @param name header name 
*/ 
public void removeHeader(String name) { 
for (int i = 0; i < headers.size(); i++) { 
    InternetHeader h = (InternetHeader)headers.get(i); 
    if (name.equalsIgnoreCase(h.getName())) { 
    h.line = null; 
    //headers.remove(i); 
    //i--; // have to look at i again 
    } 
} 
} 

无论如何,我能戏剧性地进入和归零了所有这些值来降低由MessageCache存储内存。

Field headerField = MimeMessage.class.getDeclaredField("headers"); 
headerField.setAccessible(true); 
InternetHeaders headers = (InternetHeaders) headerField.get(imapMessage); 
if (headers != null) { 
    Enumeration<?> allHeaders = headers.getAllHeaders(); 
    ArrayList<String> headerNames = new ArrayList<String>(); 
    while (allHeaders.hasMoreElements()) { 
     Header header = (Header) allHeaders.nextElement(); 
     headerNames.add(header.getName()); 
    } 
    for (String headerName : headerNames) { 
     headers.setHeader(headerName, null); 
    } 
} 

不是最漂亮的,但它将一个文件夹的内存占用从40MB减少到20MB。我会看看是否有其他方法可以做到这一点。理想情况下,我认为我会创建自己的重写IMAPMessage类,但这似乎很难进入。