版权声明:本文为博主原创文章,转载请注明出处。


  记一次压测时Java内存泄漏问题的发现过程(2017-08-14)

【前篇】

  ①20170811进行A系统与B系统之间的会话功能进行压测,加上脚本准备期间的聊天消息,预计累计聊天30w+条消息;

  ②20170814原计划加大量对会话功能进行压测,情况如下;

【应用表现】

  ①B系统前台打开报错“504”;

  ②查看后台应用CPU情况,CPU利用率高达700+%(8核);

  ③查看后台内存情况,持续FullGC,且一次FullGC的时长在9s左右,从这里可以粗略定位CPU高的原因是内存GC问题导致;

【查看应用JVM配置】

  ①请教B开发团队,loader提到应该不是JVM配置引起的问题;

【尝试进行分析】

  ①尝试使用jvisualvm进行“堆 dump”,但是因为没有内存了所以jvisualvm连接后卡死(之前测试可以正确连接并显示JVM情况);

  ②使用jmap命令“jmap -dump:format=b,file=heap.hprof pid”进行dump,dump文件有16G(修改mat配置,无奈客户端硬件差);

  ③尝试shutdown应用后重启,无法shutdown;最后使用“kill -9 pid”暴力解决无法shutdown的情况,后重启应用;

【重启后情况】

  ①使用jvisualvm查看堆内存使用情况,表现为“堆内存持续上升”;

  ②重启1小时后,dump文件进行分析,其中“java.util.concurrent.LinkedBlockingQueue$Node”占用内存高达1G,基本可以判断存在“内存泄漏”;

  “com.best.oasis.B.common.entity.messageTransship.MessageTransship”对象151MB,且有160w个MessageTransship对象;

  ③B开发Review代码:原因所在:线程池中等待执行的任务队列存在内存泄漏的问题;

正常情况:

  A应用服务器发送消息给B服务器后,B服务器接收消息后将该消息存于中间表B_messagetransship中,同时将该消息转发给B客服端,B客服端接收消息并对该条消息进行ack,ack成功后删除B_messagetransship中的该条消息。为了防止消息丢失,B有一个定时重发job,用于每隔5s将B_messagetransship表中的消息再次推送一次;

异常情况:

  1.A服务器发送给B服务器的消息存在于B_messagetransship表中后(此时状态为“PENDING_SEND”),因为网络/B客户主动退出等问题,致使B客户端并未收到来自B服务器的该消息,则该消息的状态被置为“SEND_FAILED”存在表B_messagetransship中;

  2.A服务器发送给B服务器的消息,B客服端正确收到,但是B客服端发送的ACK请求返回失败,则该消息的状态被置为“PENDING_ACK”存在表B_messagetransship中;

失败消息定时重发实现逻辑:

  每隔5s从B_messagetransship中逐个取出失败的消息记录,以链式队列的形式链接在等待执行的任务队列中,若5s内该消息被线程处理且推送状态为成功,则删除数据库表中该消息记录;若5s内该消息被线程处理但推送状态为失败,则数据库表中的该条消息记录保持不变;若5s内该消息并未来得及被线程处理,下一次定时重发任务触发时,该消息会保留第二个拷贝在待处理任务队列中,以此类推;

bug发现的诱因:

  B_messagetransship表失败推送的消息量比较大,B_messagetransship表11w+条数据,失败消息量大的原因:

  ①11907条“再见”,状态为:SEND_FAILED

  产生原因:B客户端对话完毕未接收到再见语,就发起了“{"type":"close","sid":"${sid}"}”的请求,该现象在实际中也可能产生;

  ②17120条“很高兴为您服务”,状态为:PENDING_ACK

  产生原因:压测脚本未对“很高兴为您服务”消息进行ack;

  ③剩余的8w+条,为A发送给B的对话消息,推测是在脚本准备期间产生的数据;

开发下期优化思路:

  ①为B_messagetransship表中的消息增加生存时长,若超时则直接删除;

  ②限制待执行任务队列中messageTransship对象的数量,达到一定个数则不再从B_messagetransship中获取;

测试脚本修改:

  ①增加对“开始语”与“结束语”消息的ack;

Java_内存泄漏_实例1的更多相关文章

  1. Java的内存泄漏_与C/C++对比(转载总结)

    原文网址:http://developer.51cto.com/art/201111/302465.htm Java内存泄露的理解与解决(1)   一般来说内存泄漏有两种情况.一种情况如在C/C++ ...

  2. android 内存泄漏,以及检测方法

    1.为什么会产生内存泄漏 当一个对象已经不需要再使用本该被回收时,另外一个正在使用的对象持有它的引用从而导致它不能被回收,这导致本该被回收的对象不能被回收而停留在堆内存中,这就产生了内存泄漏. 2.内 ...

  3. Android内存泄漏的本质原因、解决办法、操作实例

    今年最后一个迭代终于结束了,把过程中碰到的不熟悉的东西拉出来学习总结一下   内存泄漏的本质是:[一个(巨大的)短生命周期对象的引用被一个长生命周期(异步生命周期)的对象持有]   这个东西分为两个部 ...

  4. iOS开发_内存泄漏、内存溢出和野指针之间的区别

    今天,在工作群中,被问到了内存泄漏和野指针指向的区别,自己答的不是很好,特意回来查了资料,在博文中总结一下经验,欢迎指正. 内存泄漏:是指在堆区,alloc 或new 创建了一个对象,但是并没有放到自 ...

  5. Android内存管理(12)*「实例」用Monitor 生成.hprof文件 并分析内存泄漏

    参考 http://blog.csdn.net/xiaanming/article/details/42396507 基本步骤: 1,准备一个有内存泄漏的代码 2,如何发现内存泄漏 3,生成.hpro ...

  6. 优化内存_内存泄漏——C

    内存泄漏:  动态申请内存,没有正常释放,后续又申请内存,也没释放内存,导致内存池被全部被占用,最终再申请内存的时候失败:严格点则每次申请内存的时候判断申请到的指针是否为空,若为空NULL则表示申请失 ...

  7. 为什么JAVA的垃圾回收机制无法避免内存泄漏

    一.本文参考:    1.<深入理解java虚拟机 JVM高级特性与最佳实践>    2.http://coderevisited.com/memory-leaks-in-java/   ...

  8. 【转】Android之内存泄漏调试学习与总结

    大家有或经常碰到OOM的问题,对吧?很多这样的问题只要一出现相信大家的想法跟小马的一样,就是自己的应用:优化.优化.再优化!而且如果出现类似于OOM这样级别的问题,根本就不好处理,LogCat日志中显 ...

  9. (转)从内存管 理、内存泄漏、内存回收探讨C++内存管理

    http://www.cr173.com/html/18898_all.html 内存管理是C++最令人切齿痛恨的问题,也是C++最有争议的问题,C++高手从中获得了更好的性能,更大的自由,C++菜鸟 ...

随机推荐

  1. java算法 第七届 蓝桥杯B组(题+答案) 10.压缩变换

    10.压缩变换  (程序设计) 小明最近在研究压缩算法.他知道,压缩的时候如果能够使得数值很小,就能通过熵编码得到较高的压缩比.然而,要使数值很小是一个挑战. 最近,小明需要压缩一些正整数的序列,这些 ...

  2. 使用Django完成CRM管理系统

    CRM介绍: CRM即客户关系管理,是指企业用CRM技术来管理与客户之间的关系.在不同场合下,CRM可能是一个管理学术语,可能是一个软件系统.通常所指的CRM,指用计算机自动化分析销售.市场营销.客户 ...

  3. 【HDU2138】How many prime numbers

    [题目大意] 给n个数判断有几个素数.(每个数<=2^32) 注意多组数据 [题解] 用Rabin_Miller测试跑得飞快... /************* HDU 2138 by chty ...

  4. 平衡二叉树之RB树

    RB树(红黑树)并不追求“完全平衡”——它只要求部分地达到平衡要求,降低了对旋转的要求,从而提高了性能.由于它的设计,任何不平衡都会在三次旋转之内解决.典型的用途是实现关联数组(如C++中的map和s ...

  5. Node.js中流程控制

    Node.js中的流程控制可以使用async,在使用之前需要先安装,使用npm安装 npm install async --g 下面主要介绍4种流程控制的方式: 1.串行无关联:async.serie ...

  6. HP发送HTTP POST请求 返回结果

    HP发送HTTP POST请求 返回结果 <?php $srv_ip = '192.168.10.188';//你的目标服务地址或频道.$srv_port = 80;$url = '/demo/ ...

  7. SpringBoot 集成Mybatis时 使用通用插件Mapper 注意事项

    1.如果在SpringBoot的启动入口类上面加入注解 @MapperScan(basePackages = "com.leecx.mapper")      使用的是   org ...

  8. python3--json反序列化

    # Auther: Aaron Fan # 加载文件中的数据 import json with open('test.txt','r',encoding='utf-8') as f: info = j ...

  9. 实践作业3:白盒测试----总结与反思DAY12.

    ---恢复内容开始--- 阶段一:熟悉白盒测试方法 负责人:刘思佳 工作质量评价:用例设计详细,考虑到白盒测试基于代码,所以尽可能地覆盖更多的白盒测试方法,对系统可能存在的缺陷就更容易了解.对管理员和 ...

  10. SIP简介

    说明:以下内容来着之前下载的一份文档,现将概念部分摘录在BLog,如需要完整文档将放在文件中或留言. SIP简介,第1部分:SIP初探 时间:2006-04-07作者:Emmanuel Proulx浏 ...