java - 使用 JavaMail 将 "mail.imaps.fetchsize"属性设置为大量有什么影响?

标签 java jakarta-mail system-properties

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

props.setProperty("mail.imaps.partialfetch","false");
props.setProperty("mail.imaps.fetchsize", "1048576");
  • 这(将 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(); }
           }
         }
    
    }
    

    最佳答案

    来自 JakartaMail 常见问题解答 Retrieving large message bodies seems inefficient at times :

    If you are using the IMAP provider, you could try increasing the mail.imap.fetchsize property (the current default is 16k). This will cause data to be fetched from the server in larger chunks. Note that you risk the possibility of the JVM running out of memory when you do this.


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

    Setting fetchsize to 1048576 means that my schedule job will take this much memory always and remaining memory will be allocated to rest of my application.


    源代码挖掘for the imap package看起来 fetchsize 用于为每个 IMAPInputStream 分配一个可增长的字节数组.看来这将取决于 IMAPInputStream 的生命周期以及内存中可访问的 IMAPInputStream 数量将决定堆使用的行为方式。从您的源代码看来,它应该是相当可预测的。
    Run a memory profile在您的应用程序上调整您的堆设置。

    关于java - 使用 JavaMail 将 "mail.imaps.fetchsize"属性设置为大量有什么影响?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62474632/

    相关文章:

    java - 如何为 Android Google Analytics 添加页面标题参数

    java - 在 Quartz 内发送邮件时 java.net.URI$Parser.parse() 中的 Grails NPE

    java - 如何在 Outlook javamail 中包含签名

    java - 为测试加载系统属性

    java - 如何使 Java 中的 XPathFactory newInstance 失败?

    tomcat - AWS 中的系统属性

    Java 正则表达式匹配不正确

    Java A* 实现产生两个连接节点

    安卓S/MIME开发

    java - 给定数百万个数字流,如何近似第 90 个百分位数