使用JProfiler解决Java应用程序内存溢出问题实例

阅读更多

    前段时间基于OpenJms部署了一个消息中间件服务器,通过主题订阅模式在各个消息节点之间传递信息,但是某个类型的消息节点长时间运行后出现了内存溢出问题,最后使用JProfiler的基本线程监测功能找到问题所在,并且进行解决。

 

Java 版本 java version "1.7.0_40"

JProfiler 版本 v8.0.7

 

使用JProfiler解决Java应用程序内存溢出问题实例_第1张图片

 

1、 打开JProfiler,选择New Session

使用JProfiler解决Java应用程序内存溢出问题实例_第2张图片
 

2、 点击Attach,按ok,以便从本地JVM中选择正在运行的java程序
使用JProfiler解决Java应用程序内存溢出问题实例_第3张图片
 

3、 选择session,这里可以看到本机运行的所有java程序,我的应用ID844,因此,选择844,点击ok
使用JProfiler解决Java应用程序内存溢出问题实例_第4张图片
 

4、 可以看到JProfiler正在尝试连接到该java应用
使用JProfiler解决Java应用程序内存溢出问题实例_第5张图片
 

5、 选择Instrumention,可以使用到所有的JProfiler特性,但是对于JVM的读取可能存在一定的风险使得java应用出现异常。

使用JProfiler解决Java应用程序内存溢出问题实例_第6张图片

 

6、 设置完成后,直接ok

使用JProfiler解决Java应用程序内存溢出问题实例_第7张图片

 

7、 主界面上可以看到当前产生的对象,占用的内存比例
使用JProfiler解决Java应用程序内存溢出问题实例_第8张图片
 

8、 选择左侧栏的Telemetries,可以看到当前的内存分配和使用情况
使用JProfiler解决Java应用程序内存溢出问题实例_第9张图片
 

9、 选择左侧栏下面的Threads,可以看到当前的线程执行情况,如图可以看到,当前的运行线程(绿色部分),阻塞线程(红色部分),网络或IO线程(蓝色部分),等待线程(橙色部分)。此时节点未接受任何消息,因此线程和内存都处于平稳运行状态。

使用JProfiler解决Java应用程序内存溢出问题实例_第10张图片
 

10、 有任务消息下达时,线程数猛增
使用JProfiler解决Java应用程序内存溢出问题实例_第11张图片

 

11、 具体可以看到左侧栏Threads页面下面的线程数量

使用JProfiler解决Java应用程序内存溢出问题实例_第12张图片

 

12、 慢慢的,随着消息数量的增多,处理线程越来越多,几乎是直线上涨
使用JProfiler解决Java应用程序内存溢出问题实例_第13张图片
 

 
 
13、 至此,可以看到线程的数量在不断增多,而并不是之前预想的一旦一个线程完成就立即释放资源,因此极有可能是这里导致了内存溢出。

使用JProfiler解决Java应用程序内存溢出问题实例_第14张图片
 
 
14、 Java自己的内存回收GC正在努力工作,回收我忘记释放的资源。
使用JProfiler解决Java应用程序内存溢出问题实例_第15张图片
 

15、 很小的程序,由于内存没有处理好,cpu占用却不小
使用JProfiler解决Java应用程序内存溢出问题实例_第16张图片
 

16、 由于GC的关系,内存占用呈现出锯齿状,但由于资源未释放,总内存使用量一直在随时间增大。

此处为展示完全,因此没有达到内存溢出的地步。
使用JProfiler解决Java应用程序内存溢出问题实例_第17张图片
 

17、 经过对代码的分析,实际的执行消息处理类是单例模式,代码的意图是创建唯一的一个线程池,然后接收到消息后就将任务塞到线程池中执行。但是实际的实现却是,每接收到一个任务就创建了一个线程池,并且任务执行完后并没有回收线程池,因此导致了这个结果。

pool = Executors.newScheduledThreadPool(cnf.getServerType());

 

将其修改为

if (pool == null) {

    pool = Executors.newScheduledThreadPool(5);

}

 

 

18、 修改之后,线程的运行情况如图,已经不再重复创建无用的线程池,而是稳定在一定数量的线程,平稳运行。
使用JProfiler解决Java应用程序内存溢出问题实例_第18张图片
 

 线程运行情况
使用JProfiler解决Java应用程序内存溢出问题实例_第19张图片

 

CPU占用率 
使用JProfiler解决Java应用程序内存溢出问题实例_第20张图片
 

 

GC的活跃情况 

使用JProfiler解决Java应用程序内存溢出问题实例_第21张图片
 

 

内存占用情况
使用JProfiler解决Java应用程序内存溢出问题实例_第22张图片
 

 

 

  • 使用JProfiler解决Java应用程序内存溢出问题实例_第23张图片
  • 大小: 36.8 KB
  • 使用JProfiler解决Java应用程序内存溢出问题实例_第24张图片
  • 大小: 93.3 KB
  • 使用JProfiler解决Java应用程序内存溢出问题实例_第25张图片
  • 大小: 59.9 KB
  • 使用JProfiler解决Java应用程序内存溢出问题实例_第26张图片
  • 大小: 48.4 KB
  • 使用JProfiler解决Java应用程序内存溢出问题实例_第27张图片
  • 大小: 159.8 KB
  • 使用JProfiler解决Java应用程序内存溢出问题实例_第28张图片
  • 大小: 175.7 KB
  • 使用JProfiler解决Java应用程序内存溢出问题实例_第29张图片
  • 大小: 83.7 KB
  • 使用JProfiler解决Java应用程序内存溢出问题实例_第30张图片
  • 大小: 69.7 KB
  • 使用JProfiler解决Java应用程序内存溢出问题实例_第31张图片
  • 大小: 72.1 KB
  • 使用JProfiler解决Java应用程序内存溢出问题实例_第32张图片
  • 大小: 77.2 KB
  • 使用JProfiler解决Java应用程序内存溢出问题实例_第33张图片
  • 大小: 90.9 KB
  • 使用JProfiler解决Java应用程序内存溢出问题实例_第34张图片
  • 大小: 65.7 KB
  • 使用JProfiler解决Java应用程序内存溢出问题实例_第35张图片
  • 大小: 100.3 KB
  • 使用JProfiler解决Java应用程序内存溢出问题实例_第36张图片
  • 大小: 106.5 KB
  • 使用JProfiler解决Java应用程序内存溢出问题实例_第37张图片
  • 大小: 80.5 KB
  • 使用JProfiler解决Java应用程序内存溢出问题实例_第38张图片
  • 大小: 72.3 KB
  • 使用JProfiler解决Java应用程序内存溢出问题实例_第39张图片
  • 大小: 85.9 KB
  • 使用JProfiler解决Java应用程序内存溢出问题实例_第40张图片
  • 大小: 77.2 KB
  • 使用JProfiler解决Java应用程序内存溢出问题实例_第41张图片
  • 大小: 72 KB
  • 使用JProfiler解决Java应用程序内存溢出问题实例_第42张图片
  • 大小: 71 KB
  • 使用JProfiler解决Java应用程序内存溢出问题实例_第43张图片
  • 大小: 77.3 KB
  • 使用JProfiler解决Java应用程序内存溢出问题实例_第44张图片
  • 大小: 69 KB
  • 查看图片附件

你可能感兴趣的:(java,JProfiler,内存溢出,多线程,JVM)