JavaPNS_2.2内存泄露定位和解决

java版本ios推送架包网上用的最多的是java-apns 和 javapns,还有个才开源的http://relayrides.github.io/pushy/ 没试过不知道性能如何
java-apns 效率大于javapns 尤其是大批量消息推送的时候,公司线上跑的定时推送用的是JavaPNS_2.2,定时项目跑了一段时间就挂了,
但线上有脚本,10分钟执行一次定时脚本,如果检测定时挂了就会自动重启,这是以前公司同事在定时项目挂了的时候处理的逻辑,没有
深入研究为什么定时项目会挂。

问题定位

  • 造测试推送数据,然后本地启动项目开启jstack监控堆内存和线程的使用情况。
  • jstack监控图,可以出看来堆内存一路飙升
    堆栈
  • jmap dump出当前pid(windows下pid可以通过jstack看到)内存快照,命令如下:

    jmap -dump:format=b,file=dumfile3.hprof 20996
    
  • 利用MemoryAnalyzer分析快照信息

    通过截图分析可以看出来是因为ThreadGroup里面存了大量的NotificationThreads
    导致内存泄露
    

    MemoryAnalyzer
    MemoryAnalyzer

  • 代码跟踪
增加threadGroup.destroy(),在当前线程组里面的线程结束时候去除threadGroup的依赖
NotificationThreads work = new NotificationThreads(server, ppdList, PushMsgHelper.IPHONE_THREADS);
work.setListener(this.getListener(deviceType));// 对线程的监听,一定要加上这个监听
work.start(); // 启动线程
work.waitForAllThreads(); //等待所有线程结束*/
work.destroy();//解决内存泄露关键代码