2017-03-06 11 views
0

수백만 개의 메시지가 담긴 대형 메일 함이 있습니다. 첨부 파일이 있는지 여부에 관계없이 각 메일에 대해 배우고 싶습니다. 관심있는 크기, 이름, 첨부 파일 수, 참 거짓만으로 충분합니다. 이 코드를 사용하고 프로파일 러 도구로 모니터 할 때 message.getContent()가 메모리를 소비하고 지우지 않습니다. 수백만 개의 메시지를 처리하기 때문에 메모리 부족 문제가 발생합니다. 그 이유는 getContent() 메 메모가 일부 데이터를 캐시하고 유지하기 때문입니다.Java, IMAP, 메시지를 가져 오지 않고 첨부 파일이 있는지 확인하십시오.

getContent을 호출하지 않고이 코드의 대안은 무엇입니까? 또는 getContent에 의해 설정된 캐시를 강제로 지우려면 어떻게해야합니까? 어떻게하면이 케이스에 message.writeTo()을 적용 할 수 있습니까?

//processing million message instances in a loop i=1, 1000000 

Multipart multiPart = (Multipart) message[i].getContent(); 
for (int i = 0; i < multiPart.getCount(); i++) { 
    MimeBodyPart part = (MimeBodyPart) multiPart.getBodyPart(i); 
    if (Part.ATTACHMENT.equalsIgnoreCase(part.getDisposition())) { 
        // yes, it has an attachment 
        return true; 
    } 
} 
return false; 
+0

메시지를 보거나 보지 않음으로써 메시지를 줄일 수 있습니다. 예 : http://stackoverflow.com/questions/12988799/javamail-check-message-content-gmail-imap –

+0

일부 비즈니스 규칙으로 인해이 모든 것이 필요합니다. 헤더 (제목 등) 만 가져오고 메모리 나 성능 문제없이 본문, 첨부 파일을 무시합니다. 하지만 첨부 파일이 있거나없는 경우에만 필요합니다. 본문 및 첨부 파일을 가져 오면 나중에 사용자가 메시지를 선택할 때 수행됩니다. – benchpresser

답변

0

이것은 고전적인 Java 문제입니다. 일반적인 패턴은 루프 잎 후 각 foo를 사용하지 않는

while(true) { 
    Something foo = new Something(); 
    processSomehow(foo); 
    someCollection.add(foo); 
} 
// at this point, all of the created objects remain reachable 

이지만, JVM은 매우 큰 성장 그래서 그들은 모두, 도달 남아있다. 고전적인 솔루션은 필요하지 않은 것에 대한 참조를 유지하지 않습니다. 귀하의 경우에 message 배열은이 연결을 유지합니다.

+0

내 메시지 배열의 길이가 1 백만 개의 메시지가 아닙니다. 나는 그들을 1000 블록으로 처리하고 1000 개의 메시지를 가져 와서 처리하고, 배열을 비우고 다음으로 계속 진행합니다. getContent를 호출하지 않으면 메모리 문제가 발생하지 않습니다. – benchpresser

+1

IMAPFolder는 이와 같은 배열을 가지고 있으므로 폴더를 닫았다가 다시 열지 않는 한 가질 수 있습니다. 그래도 큰 폴더를 다시 여는 것은 매우 느립니다. [invalidateHeaders()] (https://javamail.java.net/nonav/docs/api/com/sun/mail/imap/IMAPMessage.html#invalidateHeaders--)를 호출하여 각 메시지를 더 작게 만들 수 있습니다. 그것의 문서보다는 더 많은 것을 말한다. 어쩌면 그렇게하고 50k 메시지를 다시 열면 충분합니다. – arnt

+0

고마워, 나는 오늘 이미 이것을했고 메모리가 매번 닫히면 풀려났다. 문제는 getContent로 해결되는 것 같다. 반면에 UID FETCH 및 BODYSTRUCTURE를 사용하여 customprotocol 명령을 보내려고했지만 메모리 사용량이 getContent에 비해 매우 작아서 폴더를 열거 나 닫을 필요가 없습니다. 두 방법 모두 효과가있는 것 같습니다. – benchpresser