梁野的博客转移啦
2017-04-20 03:30
采纳率: 100%
浏览 1.2k
已采纳

javamail 收邮件的时候出现out of memory

最近在做一个邮件收发的模块,其中邮件收取的模块能正常收取。因为需要收取的邮箱中的邮箱数量大概有四十万左右,所以我创建了100个线程同时收取,收取程序能正常运行,但是再运行了三四个小时之后,大概收了三万封左右的时候,每个线程就陆陆续续的报out of memory,报完异常的线程就死了,直到100个线程都报完这个异常,程序就卡死了。
这个问题困扰了我两三天了,再网上也查了不少资料,但是依旧没有解决,所以来寻求帮助,希望有遇到过这样问题的朋友能提供一下帮助,谢谢!

  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

4条回答 默认 最新

  • 梁野的博客转移啦 2017-04-25 06:32
    已采纳

    今天终于解决了这个问题。首先说明一下会产生out of memory的原因:

    因为当用javamail向邮件服务器请求邮件的时候,返回的message中包含了header等信息,javamail默然把这些message信息加入到缓存中。但是一旦我们获取的message数量太多的时候,这个message所占用的空间就非常巨大了,而且gc不会自动回收他们,所以我们需要在每次检索完该message之后让缓存失效从而释放内存空间。翻了javamail好久,才发现角落里有一个方法:

    void com.sun.mail.imap.IMAPMessage.invalidateHeaders()

    Invalidate cached header and envelope information for this message. Subsequent accesses of this information will cause it to be fetched from the server.

    这个方法的作用就是说调用该方法使缓存失效,当你要获取message时会重新从mail server获取。因为我们一般获取邮件只要获取一次就好了,所以用不着缓存,所以直接调用该方法使缓存失效即可。

    补充:另外说明一下,javamail产生out of memory错误的情况不止以上一种,还有下载大附件的时候也会出现,因为其他方式在javamail官网有方案解决,我就不在这讲解了。好了,不说了,老板叫我去搬砖了!

    已采纳该答案
    打赏 评论
  • 疯雪 2017-04-20 04:36

    你给java程序分配了多大的内存?另外你收取的这些邮件最后是放到内存中还是存盘了?存到内存的话,肯定会溢出啊。

    打赏 评论
  • 梁野的博客转移啦 2017-04-20 09:56

    我是收取下来存到数据库中

    打赏 评论
  • 梁野的博客转移啦 2017-04-24 08:46

    图片说明
    这是程序运行时的堆使用情况图

    打赏 评论

相关推荐 更多相似问题