2009-09-23 6 views
3

Je cours un serveur qui utilise Javamail. Il a un écouteur de compte avec IDLE IMAP, de sorte que lorsqu'un nouveau courrier entre, un certain morceau de code est exécuté. La liste des nouveaux messages est donnée à mon auditeur en tant que paramètre. J'ai lu l'information et j'en ai fini avec ça. Tout est bon sauf que mon serveur laisse beaucoup de mémoire !! J'ai fait un vidage de tas et j'ai trouvé que la classe [Lcom.sun.mail.imap.IMAPMessage utilise beaucoup de mémoire. Il semble qu'un tableau de IMAPMessage est référencé par l'objet com.sun.mail.imap.MessageCache.Comment forcer Javamail à effacer son cache de messages?

Y at-il un cache en cours? Je n'ai plus besoin d'accéder à ces messages, sauf pour la première fois. Comment forcer le cache à se libérer? Comment puis-je empêcher javamail de fuir?

Répondre

1

Selon le docs, vous pas un booléen pour indiquer que les messages supprimés doivent être effacés:

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

Ceci n'est pas une solution pour effacer/vider le cache de Javamail. – GreenKiwi

1

Je trouve cette référence dans le Forum Javamail How to force Javamail to clear its message cache?

Et puis a fait un peu de creuser. Bien que je n'ai pas trouvé un moyen de supprimer ou de réduire le "cache", j'ai trouvé que la plus grande partie de ce cache sont les en-têtes du message. Il y a deux copies des en-têtes à l'intérieur de IMAPMessage, une à l'intérieur et une à l'intérieur de MIMEMessage qu'il remplit. Maintenant, le problème vient quand vous voulez effacer ces informations car elles ne vous donnent accès qu'à effacer les informations dans IMAPMessage. Les en-têtes de MIMEMessage ne peuvent pas être effacés. En outre, ils ne peuvent pas être supprimés. Voici le code de 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 
    } 
} 
} 

Peu importe, je suis en mesure de diminuer la mémoire stockée par le MessageCache de façon spectaculaire en allant et en toutes annulant ces valeurs.

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); 
    } 
} 

Pas la plus jolie, mais elle diminue mon empreinte mémoire d'un dossier de 40Mo à 20Mo. Je vais voir s'il y a d'autres façons de le faire. Idéalement, je pense que je créerais ma propre classe IMAPMessage surchargée, mais cela semble très difficile à trouver.