2015-03-11 19:47 1098人阅读 评论(0) 收藏 举报
 分类:
VisualVM(8) 

版权声明:本文为博主原创文章,未经博主允许不得转载。

 

目录(?)[+]

 

Java虚拟机性能管理神器 - VisualVM(7)  排查JAVA应用程序线程泄漏

1. 线程泄漏原因

搞清楚线程泄漏原因之前,我们先了解一下什么是线程泄漏和线程溢出。(已经了解这两个概念的同学,请直接看下一节)。

泄漏:一般指工业中不应该流出或漏出的物质或流体,流出或漏出机械设备以外,造成损失,称之为泄漏(百度百科)。

线程泄漏:指系统中动态分配的线程,在使用完毕后未关闭,导致相关资源未释放,结果导致一直占据系统资源,直到系统结束。直白点说,就是线程使用完毕后没有关闭或者正常停止,即线程泄漏。

溢出:是指就是某个容器装满了东西后,再装就流出来了,即溢出。

线程溢出:指系统中达到了线程分配的极限,无法再创建新的线程时,还在收到新创建线程的请求,无法创建的一种状态,即线程溢出。

在系统中,泄漏和溢出是有因果关系的:即,发生线程泄漏后,会导致线程溢出。或者说泄漏是原因,溢出是结果。但是有时候溢出不一定是泄漏造成的,例如:目前系统允许程序最多创建100个线程,由于当前并发量大,线程池目前已有98个线程正在处理业务,如果此时又并发请求创建了5个线程,就会造成线程池溢出,但是这个不能算是线程泄漏造成的,只能算是高并发业务场景下产生的线程溢出。

弄明白线程泄漏的含义后,我们就明白了线程泄漏的原因:线程使用完后没有正常关闭导致。

再说说实际应用中的问题:在生产环境,发生了数据修改后不更新的问题。业务逻辑是修改组织数据后,会将修改信息通过消息中间件通知订阅的服务,订阅的服务收到通知后,根据修改的信息更新缓存中的数据。由于缓存中的数据没有更新,所以刚开始怀疑是消息中间件没有传输成功。

2. 线程泄漏排查

有了排查目标后,就跟踪日志进行排查,发现消息能到应用服务接收方,说明消息传输成功,是应用收到消息后没有更新导致。那么就通过VisualVM远程监控JVM的运行状态,首先发现内存异常,Old区内存满了,说明有资源没有释放,而监视页面显示实时线程接近5000个,而一般应用的线程基本在100以下,说明线程运行不正常。将程序放到本机进行运行,查看线程标签,显示出具体业务线程运行后,一直处于运行和休眠状态,排查具体业务线程的逻辑,发现是在调用线程的逻辑中,每次都新建了一个业务线程,调用的任务又是通过定时器每隔几分钟运行一次,而业务线程只需要启动一次就行了,重复调用就会导致业务线程不断创建,最终导致线程资源泄漏而产生溢出,影响其他业务正常运行。

3. 线程泄漏处理

发现线程泄漏后,根据业务逻辑,将对应的代码进行重构,将定时调用的业务线程,做成静态方法进行调用,或者在调用任务类中,业务线程作为参数进行引用,避免重复创建。

最新文章

  1. perl 对源文件内容修改 方法整理
  2. SOS.dll (SOS Debugging Extension)
  3. [LeetCode]题解(python):060-Permutation Sequence
  4. mysql 线程池 数据库连接池
  5. gomobile 真机 log 打出的日志跟踪
  6. Python图片处理PIL/pillow/生成验证码/出现KeyError: 和The _imagingft C module is not installed
  7. php json_encode转JSON 编码显示中文
  8. 加密算法 - RSA
  9. ajax请求aspx页面
  10. android 隔几秒再执行
  11. Formiko总结整数十进制转换二进制原理
  12. python成长之路——第四天
  13. LeetCode 243. Shortest Word Distance (最短单词距离)$
  14. linux下redis单机版搭建
  15. 腾讯云“智能+互联网TechDay”:揭秘智慧出行核心技术与创新实践
  16. 其于OpenXml SDK写的帮助类
  17. Springboot 2.0.4 整合Mybatis出现异常Property 'sqlSessionFactory' or 'sqlSessionTemplate' are required
  18. 安卓开发笔记——关于Handler的一些总结(上)
  19. Redis 基础:Redis 事件处理
  20. [na]非对称加密方式&带加密的数字签名交互流程

热门文章

  1. AtCoder ABC 126F XOR Matching
  2. CVE-2018-3246 weblogic xxe
  3. 可搭建SS服务上网的不限流量VPS推荐
  4. <读书笔记>如何入门爬虫?
  5. OpenCV-Python Tutorials目录
  6. (转)lua protobuffer的实现
  7. 【模板篇】A* 寻路算法
  8. PHP算法之IP 地址无效化
  9. 既然 start() 方法会调用 run() 方法,为什么我们调用 start() 方法,而不直接调用 run() 方法?
  10. canvas填充规则,非零环绕