有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

使用fetchprofileitem时,电子邮件Java mail、IMAP内存不足。getcontent期间的消息

我使用javamail api和IMAP协议从巨大的邮箱(一个文件夹包含1.000.000封邮件和附件)获取包含内容和附件的邮件。我的问题是,当我使用FetchProfileItem.MESSAGE进行性能测试时,我在执行该部分时会遇到内存问题。getContent()

假设我们有2000封邮件,它们的UID编号为1-2000。(我知道他们可能会有所不同)。首先,我们得到所有的消息模板

Message allMessages[] = folder.getMessagesByUID(0, 2000);

然后,我们使用fetch配置文件来获取消息,但我们只获取第一个块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]);

现在我们使用fetch profile来获取第一组(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 first组,则生成一个新的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并处理消息。但在完成第一个块后,内存资源不会被释放,执行第二组操作时会使用额外的内存,直到内存耗尽为止

在body进程中删除part.getContent()调用时,不会出现内存问题。此外,如果我从fetch配置文件中删除FetchProfileItem.MESSAGE,内存问题就结束了

我知道,fetch profile消息会对所有数据执行预回迁,提高getContent调用的性能,并提高性能,但为什么即使单个消息的处理已经完成,内存使用率也会一直增加


共 (0) 个答案