2009-12-22 10 views
0

Est-ce que l'API java mail utilise le streaming? où puis-je obtenir le code source pour le confirmer. aussi j'essaye d'envoyer le courrier en utilisant le mode cru et non-cru. en mode brut je peux passer un flux d'entrée au constructeur MimeMessage: [/ b]Mémoire insuffisante en utilisant le courrier java

new MimeMessage(session, doc.getBodyInputStream()); 

En mode non-cru, je dois faire la suivante Comme il peut y avoir tout type mime, donc je dois utiliser DataHandler et DataSource. Depuis les contrats d'interface DataSource dit de fournir le inputStream frais chaque fois que nous invoquons getInputStream(), nous devons conserver les données dans le byte[] qui va lancer OOM pour les documents de grande taille ou des documents Y at-il un moyen d'éviter cela?

MimeMessage msg = new MimeMessage(session); 
byte[] bArr = doc.getBody(); 
ByteArrayInputStream ins = new ByteArrayInputStream(
    bArr != null && bArr.length > 0 ? bArr : "".getBytes()); 
msg.setDataHandler(new DataHandler(new ByteArrayDataSource(ins, mimeType))); 
+1

Si vous ne parvenez pas à conserver la pièce jointe en mémoire, dans quelle mesure pensez-vous que le réseau de messagerie la gérera? – skaffman

Répondre

0

En ce qui concerne l'OOM, en général vos e-mails ne devrait pas être plus grand que 10 Mo, ce qui ne devrait pas être garder plus de 10 Mo dans le tableau d'octets.

Est-ce une question théorique? Ou voyez-vous réellement cela arriver?

Si cela se produit, augmentez la taille de la pile, car le code ci-dessus semble plus ou moins correct.

0

Est-il possible de vider le corps dans un fichier (temporaire), laisser le bArr jeté hors de la portée (ou mettre à null) et ensuite utiliser le FileDataSource?

1

Le problème se produit-il si vous ne traitez qu'un seul courrier ou obtenez-vous un MOO après le traitement (et la mise en cache!) De plusieurs courriels?

Augmenter la taille du tas est une option, mais si cela augmente le temps avant que le prochain MOO ne vous blesse, alors vous songez à des alternatives pour garder les tableaux d'octets bruts en mémoire.

Et vous devez utiliser le constructeur ByteArrayDataSource(byte[] bArr, String type), cela empêche de dupliquer le tableau d'octets complet en mémoire, car le bArr est simplement stocké dans le DataSource tel qu'il est. L'autre constructeur commence avec un tableau de 8 octets et double sa taille chaque fois que plus d'espace est nécessaire - cela gaspille beaucoup de mémoire et peut être la cause de votre problème. (source)

+0

Ours est un produit B2B fournissant cela comme l'une des fonctionnalités et oui je comprends ByteArrayDataSource (byte [] bArr, type String) ne conservera qu'une copie de byte [], mais la taille du courrier client est de 1 Gig qui échouera simplement nous mettons les données en mémoire au lieu d'utiliser le streaming. –

+0

Mais un ByteArrayDataSource stockera toujours les données du tableau d'octets en mémoire, et s'il est créé à partir d'un flux d'entrée, il créera (et redimensionnera) un tableau d'octets interne pour les données. Un mail de 1 GByte? Oh mon Dieu... –