2009-09-23 66 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類,但這似乎很難進入。