记一次内存泄漏DUMP分析

自从进入一家创业公司以后,逐渐忙成狗,却无所收获,感觉自身的技术能力用武之地很少,工作生活都在业务逻辑中颠倒。

前些天线上服务内存吃紧,让运维把DUMP拿下来,分析一下聊以自慰。

先来统计一下大对象信息

0:000> !dumpheap -min 85000 -stat
Statistics:
              MT    Count    TotalSize Class Name
000007feec34c168        7     57734750 System.Char[]
000007feec34aee0       14    115469904 System.String
00000000013032d0      101    621925414      Free
Total 122 objects
Fragmented blocks larger than 0.5 MB:
            Addr     Size      Followed by
000000010d382018    2.8MB 000000010d645e90 System.String
000000010d971aa8    1.8MB 000000010db43530 System.Random
000000010db70bd0    1.1MB 000000010dc8e238 System.String
000000010dd2f6a8    0.7MB 000000010ddd9160 System.Random
000000010ddd92e8    1.1MB 000000010dee8d38 System.Security.Cryptography.SafeHashHandle
000000010e223090    3.0MB 000000010e51dcc8 System.Random

看看字符串

0:000> !dumpheap -type System.String -min 85000
         Address               MT     Size
00000004ffed5250 000007feec34aee0 12721650
0000000501f4aec0 000007feec34aee0  1322018
000000050208dae8 000007feec34aee0  1322022
00000005021d0710 000007feec34aee0 12726120
0000000502df3678 000007feec34aee0 12726124
00000005121b3168 000007feec34aee0 12726120
000000052001c2b0 000007feec34aee0 12721654
0000000521053930 000007feec34aee0   732168
00000005211b9120 000007feec34aee0   732168
00000005216efa08 000007feec34aee0 12726124
0000000522312978 000007feec34aee0 12726124
00000005307564d8 000007feec34aee0  4780744
0000000531074a50 000007feec34aee0  4780748
0000000531503d20 000007feec34aee0 12726120     

Statistics:
              MT    Count    TotalSize Class Name
000007feec34aee0       14    115469904 System.String

查看字符串详情

0:000> !DumpObj /d 0000000501f4aec0
Name:        System.String
MethodTable: 000007feec34aee0
EEClass:     000007feebcb3720
Size:        1322018(0x142c22) bytes
File:        C:\Windows\Microsoft.Net\assembly\GAC_64\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll
String:      {"SalePriceStrategyList":[{"SaleRuleID":5178,"StrategyTypeID":5,"StrategyTypeName":"标准售......

  

0:000> dc 00000004ffed5250 L1000
00000004`ffed5250  ec34aee0 000007fe 00610eec 0022007b  ..4.......a.{.".
00000004`ffed5260  00720050 0064006f 00630075 00490074  P.r.o.d.u.c.t.I.
00000004`ffed5270  00220064 0034003a 00390037 002c0031  d.".:.4.7.9.1.,.
00000004`ffed5280  00500022 006f0072 00750064 00740063  ".P.r.o.d.u.c.t.
00000004`ffed5290  0061004e 0065006d 003a0022 4e3d0022  N.a.m.e.".:.".=N
00000004`ffed52a0  002d6c5f 683c9999 62c991cc 901a76f4  _l-...<h...b.v..
00000004`ffed52b0  00228f66 0022002c 00750053 004e0062  f.".,.".S.u.b.N.
00000004`ffed52c0  006d0061 00220065 0022003a 002c0022  a.m.e.".:.".".,.
00000004`ffed52d0  00440022 00700065 00610052 0067006e  ".D.e.p.R.a.n.g.
00000004`ffed52e0  004c0065 00730069 00220074 006e003a  e.L.i.s.t.".:.n.
00000004`ffed52f0  006c0075 002c006c 00440022 00730065  u.l.l.,.".D.e.s.
00000004`ffed5300  00520074 006e0061 00650067 0069004c  t.R.a.n.g.e.L.i.
00000004`ffed5310  00740073 003a0022 007b005b 00520022  s.t.".:.[.{.".R.
00000004`ffed5320  006e0061 00650067 00640049 003a0022  a.n.g.e.I.d.".:.
00000004`ffed5330  00330022 00220037 0022002c 00610052  ".3.7.".,.".R.a.
00000004`ffed5340  0067006e 004e0065 006d0061 00220065  n.g.e.N.a.m.e.".
00000004`ffed5350  0022003a 6c5f4e3d 002c0022 00450022  :.".=N_l".,.".E.
00000004`ffed5360  004e006e 006d0061 00220065 0022003a  n.N.a.m.e.".:.".
00000004`ffed5370  0069004c 0069006a 006e0061 00220067  L.i.j.i.a.n.g.".
00000004`ffed5380  0022002c 00610052 0067006e 00540065  ,.".R.a.n.g.e.T.
00000004`ffed5390  00700079 00220065 0031003a 002c0036  y.p.e.".:.1.6.,.

发现是指纹或销控缓存反序列产生的

同理看看字符数组,结果类似。

继续,分析线程

0:000> !threads
ThreadCount:      1710
UnstartedThread:  1
BackgroundThread: 122
PendingThread:    0
DeadThread:       1587
Hosted Runtime:   no

发现deadthread很多,用类似的方式,发现这些线程的地址都在终结器队列GCHandle中,推测室短时间内AMQ批量触发而无法大量共用线程池中的现有线程引起新开辟了很多额外的线程。通过调用栈发现的确如此:

0:000> !clrstack
OS Thread Id: 0x5718 (42)
        Child SP               IP Call Site
0000000013e8e6c8 000000007706df6a [GCFrame: 0000000013e8e6c8]
0000000013e8e798 000000007706df6a [HelperMethodFrame_1OBJ: 0000000013e8e798] System.Threading.Monitor.ObjWait(Boolean, Int32, System.Object)
0000000013e8e8b0 000007fe9302c6da Apache.NMS.ActiveMQ.Threads.DedicatedTaskRunner.Run()
0000000013e8e930 000007feec19f8a5 System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
0000000013e8ea90 000007feec19f609 System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
0000000013e8eac0 000007feec19f5c7 System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object)
0000000013e8eb10 000007feec1b2d21 System.Threading.ThreadHelper.ThreadStart()
0000000013e8ee28 000007feed27f713 [GCFrame: 0000000013e8ee28]
0000000013e8f158 000007feed27f713 [DebuggerU2MCatchHandlerFrame: 0000000013e8f158]
0000000013e8f338 000007feed27f713 [ContextTransitionFrame: 0000000013e8f338]
0000000013e8f528 000007feed27f713 [DebuggerU2MCatchHandlerFrame: 0000000013e8f528]

推测是由于AMQ短时间内批量触发指纹、销控缓存更新引起。

本来想着手解决缓存反序列化大对象、改善AMQ批量触发开辟过多线程、以及是否有未退订的订阅等问题,不过产品过来说,业务码好了没》》》

时间: 2024-11-01 23:05:13

记一次内存泄漏DUMP分析的相关文章

实战Java内存泄漏问题分析 -- hazelcast2.0.3使用时内存泄漏 -- 1

公司当年有一个自己缓存集群用户session的Java library,是基于hazlcast2.0.3实现的,最近在customer site集群环境中某个blade报了Out of Memory Exception, 其他blades都正常,马上用jrockit jrcmd命令dump了堆和线程进行分析. printf "##################### heap ##################\n" su -p occas -c "/opt/jrocki

实战Java内存泄漏问题分析 -- hazelcast2.0.3使用时内存泄漏 -- 2

hazelcast 提供了3中方法调用startCleanup: 第一种是在ConcuurentMapManager的构造函数中,通过调用node的executorManager中的ScheduledExecutorService来创建每秒执行一次cleanup操作的线程(代码如下).由于这是ConcuurentMapManager构造函数的代码,所以这种调用startCleanup的操作是默认就会有的. node.executorManager.getScheduledExecutorServ

记一次内存溢出的分析经历

背景: 有一个项目做一个系统,分客户端和服务端,客户端用c++写的,用来收集信息然后传给服务端(客户端的数量还是比较多的,正常的有几千个), 服务端用Java写的(带管理页面),属于RPC模式,中间的通信框架使用的是thrift. thrift很多优点就不多说了,它是facebook的开源的rpc框架,主要是它能够跨语言,序列化速度快,但是他有个不讨喜的地方就是它必须用自己IDL来定义接口 thrift版本:0.9.2. 问题定位与分析 步骤一.初步分析 客户端无法连接服务端,查看服务器的端口开

android内存泄漏系列- 分析hprof文件

转载请注明出处 http://www.cnblogs.com/weiwangnuanyang/p/5703702.html ,谢谢. 如果只是想确定一下某一个场景是否有内存泄漏,AndroidStadio的控制台就有一个好工具,反复操作观察曲线是否上扬,如果曲线上扬则说明内存泄漏 但是,上面的工具不够强大,不能看出内存中驻留的具体的类和类的引用关系. 下面就来重点介绍一下,解决android内存泄漏必备利器-Memory Analysis; 具体安装方式请移步度娘. 我们这里重点介绍如何利用Me

JVisualVM简介与内存泄漏实战分析

一.JVisualVM能做什么 VisualVM 是Netbeans的profile子项目,已在JDK6.0 update 7 中自带(java启动时不需要特定参数,监控工具在bin/jvisualvm.exe),能够监控线程,内存情况,查看方法的CPU时间和内存中的对 象,已被GC的对象,反向查看分配的堆栈(如100个String对象分别由哪几个对象分配出来的). 在JDK_HOME/bin(默认是C:\Program Files\Java\jdk1.6.0_13\bin)目录下面,有一个jv

Yii2 框架跑脚本时内存泄漏问题分析

现象 在跑 edu_ocr_img 表的归档时,每跑几万个数据,都会报一次内存耗尽 PHP Fatal error: ?Allowed memory size?of 134217728 bytesexhausted (tried?toallocate?135168 bytes) 跟踪代码发现,是在插入时以下代码造成的: EduOCRTaskBackup::getDb()->createCommand()->batchInsert(EduOCRTaskBackup::tableName(), $

AndroidStudio 内存泄漏的分析过程

前言部分这次泄漏是自己代码写的太随意引起的,讲道理,代码写的太为所欲为了,导致有些问题根本就很难发现. 泄漏产生的原因,由于activity未被回收导致.这里给我们提出的一个警示,在使用上下文的时候,我们要特别注意,尤其是一些实例的上下文,如:activity.fragment等. 这次的错误原因就是我把activity作为上下文传给了Glide使用,结果后期我做夜间模式,需要重启activity让夜间模式生效的时候忘记Glide还在持有activity的引用导致了泄漏. 内容部分产生了泄漏的时

记一次内存泄漏问题排查

通过MonitoSDK的Sample App进行试用时,发现存在部分内存泄漏的情况,leakcanary直接弹出提示如下 可以看到MonitorDBActivity的instance导致泄漏. @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_db); ButterKnife.bind

记一次内存溢出的分析经历——thrift带给我的痛orz

说在前面的话 朋友,你经历过部署好的服务突然内存溢出吗? 你经历过没有看过Java虚拟机,来解决内存溢出的痛苦吗? 你经历过一个BUG,百思不得其解,头发一根一根脱落的烦恼吗? 我知道,你有过! 但是我还是要来说说我的故事.................. 背景: 有一个项目做一个系统,分客户端和服务端,客户端用c++写的,用来收集信息然后传给服务端(客户端的数量还是比较多的,正常的有几千个), 服务端用Java写的(带管理页面),属于RPC模式,中间的通信框架使用的是thrift. thri