我使用javamail api和IMAP协议从大邮箱(文件夹包含1.000.000邮件和附件)中获取包含内容和附件的邮件。我的问题是,当我使用 FetchProfileItem.MESSAGE
来提高性能时,我在执行part.getContent()时会遇到内存问题。
假设我们有2000封邮件,他们的UID编号为1-2000。 (我知道他们可能会有所不同)。首先,我们获取所有消息模板。
Message allMessages[] = folder.getMessagesByUID(0, 2000);
然后我们使用获取配置文件获取消息,但我们只获取第一个0-1000块消息以防止大量内存消耗。
ArrayList<message> firstGroup = new ArrayList<message>();
for (i = 0; i < 1000; i++)
firstGroup.add(allMessages[i]);
// convert it to message array
Message firstGroupMessages [] = firstGroup.toArray(new Message[0]);
现在我们使用获取配置文件来获取第一组(0-1000)的所有消息数据
FetchProfile fp = new FetchProfile();
fp.add(FetchProfileItem.Message);
// other items such as Envelope, flags, content info, x-mailer etc.
folder.fetch(firstGroupMessages , fp);
// and we process the messages
for (Message m : firstGroupMessages ) {
processHeader(m);
processBody(m);
((IMAPMessage)m).invalidateHeaders(); // i do not need this message anymore
}
void processBody(Part p) {
...
// any call to p.getContent causes huge memory consumption
Object o = p.getContent();
if (o instanceof InputStream) {
...
当我在0-1000范围内运行此部件时,将分配一个内存块。如果完成第一个块的处理,并清除arraylist第一组,则生成一个新的arraylist并从消息数组allMessages中获取UID 1000-2000的消息。
ArrayList<message> secondGroup = new ArrayList<message>();
for (i = 1000; i < 2000; i++)
secondGroup .add(allMessages[i]);
// convert it to message array
Message secondGroupMessages [] = secondGroup .toArray(new Message[0]);
然后再次调用fetchprofile并处理消息。但是在完成第一个块之后,内存资源没有释放,执行第二个组会占用额外的内存,直到内存不足为止。
当我在正文过程中删除part.getContent()
次调用时,不会出现内存问题。此外,如果我从获取配置文件中删除FetchProfileItem.MESSAGE
,则内存问题已经结束。
我知道,获取配置文件MESSAGE会对所有数据执行预取并提高getContent调用的性能并提高性能,但是为什么即使单个消息的处理已完成,内存使用量也会增加?