设置「;mail.imaps.fetchsize“;使用JavaMail将属性设置为大量有何影响?

设置「;mail.imaps.fetchsize“;使用JavaMail将属性设置为大量有何影响?,java,jakarta-mail,system-properties,Java,Jakarta Mail,System Properties,我有一个日程安排工作,从文件夹中获取最近的电子邮件,并将这些电子邮件写入一个文件(.eml文件)。但是要花很长时间(阅读一封9mb大小的电子邮件需要5到6分钟)才能完成。因为我使用的是JavaMail API,所以我在代码中设置了如下属性以提高性能,这样做所用的时间非常少(20秒) 这(将fetchsize设置为更大的值)是否会在我的应用程序中产生任何其他问题 将fetchsize设置为1048576意味着我的计划作业将占用 总是会有这么多内存,剩余的内存将分配给 我申请的其余部分。我的理解正确

我有一个日程安排工作,从文件夹中获取最近的电子邮件,并将这些电子邮件写入一个文件(.eml文件)。但是要花很长时间(阅读一封9mb大小的电子邮件需要5到6分钟)才能完成。因为我使用的是JavaMail API,所以我在代码中设置了如下属性以提高性能,这样做所用的时间非常少(20秒)

  • 这(将
    fetchsize
    设置为更大的值)是否会在我的应用程序中产生任何其他问题
  • 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(); }
           }
         }
    
    }
    
    package.com.incide;
    导入java.io.File;
    导入java.io.FileOutputStream;
    导入java.io.IOException;
    导入java.io.OutputStream;
    导入java.util.Properties;
    导入javax.mail.Flags;
    导入javax.mail.Folder;
    导入javax.mail.Message;
    导入javax.mail.MessaginException;
    导入javax.mail.NoSuchProviderException;
    导入javax.mail.Session;
    导入javax.mail.Store;
    导入javax.mail.search.FlagTerm;
    公共类读邮件{
    公共静态void main(字符串[]args)引发InterruptedException、IOException{
    字符串协议=“imaps”;
    字符串emailAddress=“email\u id”;
    字符串password=“password”;
    Properties props=新属性();
    props.setProperty(“mail.store.protocol”,protocol);
    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);
    试一试{
    Store Store=session.getStore(协议);
    store.connect(“imap mail.outlook.com”、电子邮件地址、密码);
    文件夹收件箱=store.getFolder(“归档/测试”);
    收件箱。打开(文件夹。读写);
    //搜索所有“看不见”的消息
    最近的标志=新标志(Flags.Flag.recent);
    FlagTerm recentFlagTerm=新FlagTerm(最近,为真);
    messages[]=收件箱.搜索(recentFlagTerm);
    for(int i=0;i
    来自JakartaMail常见问题解答:

    如果您使用的是IMAP提供程序,可以尝试增加mail.IMAP.fetchsize属性(当前默认值为16k)。这将导致数据以较大的块从服务器中获取。请注意,这样做可能会导致JVM内存不足

    正如你所指出的,你只需要足够的堆空间

    将fetchsize设置为1048576意味着我的调度作业将始终占用这么多内存,剩余内存将分配给应用程序的其余部分

    在源代码中,fetchsize似乎用于为每个
    IMAPInputStream
    分配一个可增长的字节数组。看起来这将取决于IMAPInputStream的生存期,内存中可访问的IMAPInputStream数量将决定堆的使用行为。从您的源代码来看,它应该是相当可预测的

    在应用程序上调整堆设置

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