我使用javamail通过IMAP协议从exchage帐户读取邮件。这些邮件是纯格式的,内容是XML。
几乎所有这些邮件的大小都很短(通常小于100Kb)。然而,有时我不得不处理大型邮件(大约10Mb-15Mb)。例如,昨天我收到一封13Mb大小的电子邮件。仅仅读它就花了50多分钟。这正常吗?有没有办法提高它的性能?代码是:
Session sesion = Session.getInstance(System.getProperties());
Store store = sesion.getStore("imap");
store.connect(host, user, passwd);
Folder inbox = store.getFolder("INBOX");
inbox.open(Folder.READ_WRITE);
Message[] messages = inbox.search(new FlagTerm(new Flags(Flags.Flag.SEEN), false));
for (int i = 0 ; i< messages.length ; i++){
Object contents = messages[i].getContent(); // Here it takes 50 min on 13Mb mail
// ...
}
花费如此长时间的方法是messages[i]。getContent()
。我做错了什么?有什么提示吗?
非常感谢,我的英语很抱歉!;)
使用文件夹。fetch方法您可以在一次操作中预取多条消息的元数据。这将减少处理每条消息的时间,但对处理大量消息没有多大帮助。
如果要高效地处理巨大的消息部分,通常需要使用getInputStream方法以增量方式处理数据,而不是使用getContent方法读取其中的所有数据并创建包含所有数据的巨大字符串对象。
还可以通过指定“mail.imap.fetchsize”属性(默认值为16384)来优化抓取。如果您的大多数邮件小于100K,并且您总是需要读取邮件中的所有数据,那么可以将fetchsize设置为100K。这将使小消息更快,大消息更高效。
它永远是信息[i]。getContent()这将是代码中最慢的部分。原因通常是IMAP服务器不会缓存这部分消息数据。不过,你可以试试这个:
FetchProfile fp = new FetchProfile();
fp.add(FetchProfile.Item.ENVELOPE);
fp.add(FetchProfileItem.FLAGS);
fp.add(FetchProfileItem.CONTENT_INFO);
fp.add("X-mailer");
and after you have specified the fetch profile then you do your search/fetch of messages.
基本上,其概念是IMAP提供者仅在必要时从服务器获取消息的数据。(javax.mail.FetchProfile用于优化此功能)。头和正文结构信息一旦被获取,就会被缓存在消息对象中。但是,bodypart的内容不会被缓存。因此,每次客户端请求内容时(使用getContent()或getInputStream()),都会向服务器发出一个新的获取请求。这是因为消息的内容可能很大,如果我们将此内容缓存为大量消息,系统可能很快就会耗尽内存,因为垃圾收集器无法释放引用的对象。客户应该意识到这一点,如果需要,必须保留检索到的内容。
通过使用上面提到的代码片段,你可以“希望”提高一些速度,但这完全取决于你的SMTP服务器,如果这将工作与否。由于上一段提到的负载问题,所有大型SMTP服务器都不支持这种行为,因此您可能无法获得任何速度。
我终于解决了这个问题,想与大家分享。
在这个网站上找到了解决方案,至少对我有效:http://www.oracle.com/technetwork/java/faq-135477.html#imapserverbug
因此,我在第一篇帖子中输入的原始代码变成:
Session sesion = Session.getInstance(System.getProperties());
Store store = sesion.getStore("imap");
store.connect(host, user, passwd);
Folder inbox = store.getFolder("INBOX");
inbox.open(Folder.READ_WRITE);
// Convert to MimeMessage after search
MimeMessage[] messages = (MimeMessage[]) carpetaInbox.search(new FlagTerm(new Flags(Flags.Flag.SEEN), false));
for (int i = 0 ; i< messages.length ; i++){
// Create a new message using MimeMessage copy constructor
MimeMessage cmsg = new MimeMessage(messages[i]);
// Use this message to read its contents
Object obj = cmsg.getContent();
// ....
}
诀窍是,使用mimessage()复制构造函数,创建一个新的mimessage并读取其内容,而不是原始消息。您应该注意,这样的对象并没有真正连接到服务器,所以您对它所做的任何更改,比如设置标志,都不会生效。消息的任何更改都必须在原始消息上进行。
总而言之:该解决方案适用于使用IMAP协议读取连接到Exchange Server的大型纯文本邮件(高达15Mb)。泰晤士报将阅读13Mb邮件的51-55分钟降低到阅读相同邮件的9秒。难以置信。
希望这能帮助别人,并为英语错误感到抱歉;)
给出结果需要20多秒,而在mongo控制台中同样的查询需要不到一秒。 为什么会出现这种情况,如何减少速度差距?
我有以下PHP代码在Laravel正在执行一个MySql查询: 执行此查询需要很长时间。 我对所排序的列以及其他查询的许多列都有索引。 我该怎么办? 更新: 执行的查询: 结果:
问题内容: 我在重新整理模型时遇到问题。我训练了模型并使用此代码保存了模型。我不太确定这是否是正确的方法,我将不胜感激。当我尝试还原模型时会发生问题。我只需要预测,就不会再接受过培训了。从模型中恢复参数需要花费很多时间。在我仅需要预测的前提下,如何改进模型保护程序或模型恢复程序以使其快速完成。 恢复: 编辑:也许使用Google Colab的GPU训练模型,然后将其还原到我的PC上这一事实很重要。
在我们的kafka broker设置中,GC平均需要20毫秒,但随机增加到1-2秒。极端情况持续9秒。这种情况的发生频率相当随机。平均每天发生15次。我尝试过使用GCEasy,但没有给出任何见解。我的内存使用率为20%,但进程仍然使用交换,尽管内存可用。感谢您对如何将其最小化的任何意见 JVM选择: GC日志:
问题内容: 我正在使用Hibernate 4.2,JPA 2.0和Postgres 9.2 代码卡在 在进一步调查中,我发现Hibernate调用了class 方法。此方法尝试加载有关每个数据库对象的元数据 的代码是Postgers的JDBC驱动程序的一部分,而确实是花费时间来执行该方法的驱动程序(我加载了驱动程序源并尝试了跟踪)。但是由于这个问题在Hibernate 3.3(我之前使用过)中没有
我知道要冬眠。我有一个sql语句 我尝试用createCriteria和HQL实现它。 HQL: 问题是,此HQL的执行时间延长了10倍。并执行许多不必要的查询。我尝试使用注释字符串进行转换,它有了一些改进,但仍然比createCriteria查询长5倍,此外,我无法进行此转换 <代码>列表 版本数据防御