Установка большого числа для свойства mail.imaps.fetchsize с помощью JavaMail имеет какое-либо влияние? - PullRequest
2 голосов
/ 19 июня 2020

У меня есть задание по расписанию: получить последние электронные письма из папки и записать их в файл (файл .eml). Но до завершения sh требовалось много времени (от 5 до 6 минут, чтобы прочитать письмо размером 9 МБ). Поскольку я использую JavaMail API, я установил свойства, как показано ниже, в моем коде, чтобы улучшить производительность, и, таким образом, это заняло гораздо меньше времени (20 секунд).

props.setProperty("mail.imaps.partialfetch","false");
props.setProperty("mail.imaps.fetchsize", "1048576");
  1. Это ( установка fetchsize на большее значение) создавать какие-либо другие проблемы в моем приложении?.
  2. Установка fetchsize на 1048576 означает, что мое задание расписания всегда будет занимать столько памяти, а оставшаяся память будет выделена для остальной части мое заявление. Я правильно понимаю здесь? Если нет, может ли кто-нибудь помочь мне лучше понять это на примере?.

Весь код, как показано ниже,

package com.indiscover;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

import java.util.Properties;

import javax.mail.Flags;
import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.NoSuchProviderException;
import javax.mail.Session;
import javax.mail.Store;
import javax.mail.search.FlagTerm;

public class ReadMail {

    public static void main(String[] args) throws InterruptedException, IOException {
        String protocol="imaps";
        String emailAddress = "email_id";
        String password = "password";

        Properties props = new Properties();
        props.setProperty("mail.store.protocol", protocol);
        props.setProperty("mail.imaps.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
        props.setProperty("mail.imaps.socketFactory.fallback", "false");
        props.setProperty("mail.imaps.port", "993");
        props.setProperty("mail.imaps.socketFactory.port", "993");
        props.setProperty("mail.imaps.partialfetch","false");
        props.setProperty("mail.imaps.fetchsize", "1048576"); 

        Session session = Session.getInstance(props, null);

        try {

            Store store = session.getStore(protocol);
            store.connect("imap-mail.outlook.com", emailAddress, password);
            Folder inbox = store.getFolder("Archive/Test");
            inbox.open(Folder.READ_WRITE);

            //search for all "unseen" messages
            Flags recent = new Flags(Flags.Flag.RECENT);
            FlagTerm recentFlagTerm = new FlagTerm(recent, true);
            Message messages[] = inbox.search(recentFlagTerm);


            for (int i = 0; i < messages.length; i++) {
                Message message = messages[i];
                String subject = message.getSubject();

                processSaveToFile(message,subject);
            }

            inbox.close(false);
            store.close();

        }catch (NoSuchProviderException ex) {
            System.out.println("No provider.");
            ex.printStackTrace();
        } catch (MessagingException ex) {
            System.out.println("Could not connect to the message store.");
            ex.printStackTrace();
        }

    }

    private static void processSaveToFile (Message msg, String subject) throws MessagingException, IOException
    {
       String whereToSave = "/Users/XXX/Documents/" + "some_random_name" + ".eml";

       OutputStream out = new FileOutputStream(new File(whereToSave));
       try {
           msg.writeTo(out);
       }
       finally {
           if (out != null) { out.flush(); out.close(); }
       }
     }

}

1 Ответ

0 голосов
/ 03 июля 2020

Из FAQ JakartaMail Иногда получение больших тел сообщений кажется неэффективным :

Если вы используете IMAP-провайдер, вы можете попробовать увеличить свойство mail.imap.fetchsize (текущее значение по умолчанию - 16k). Это приведет к тому, что данные будут извлекаться с сервера большими порциями. Обратите внимание, что вы рискуете, что при этом у JVM закончится нехватка памяти.

Как вы указали, вам просто нужно достаточно места в куче. означает, что мое задание по расписанию всегда будет занимать столько памяти, а оставшаяся память будет выделена для остальной части моего приложения.

Копаться в исходном коде для пакета imap похоже fetchsize используется для выделения растущего байтового массива на IMAPInputStream. Похоже, это будет зависеть от времени жизни IMAPInputStream, а количество доступных IMAPInputStream в памяти будет определять, как будет вести себя использование кучи. Судя по исходному коду, все должно быть достаточно предсказуемым.

Запустите профиль памяти в своем приложении, чтобы настроить параметры кучи.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...