【发布时间】:2017-12-06 19:04:31
【问题描述】:
我有一个有状态服务,它消耗越来越多的内存,直到服务重新启动或进程被杀死,然后释放内存。
见下图;它看起来像是典型的锯齿型内存泄漏问题。
我们使用 DotMemory 对集群中单个节点的内存使用情况进行了一些分析,它报告所消耗的绝大多数内存都在非托管内存中。
就在我们循环有状态服务之前,我们获取了一个内存转储文件,以查看是否可以使用 WinDbg 进一步了解任何内容。
我不是 WinDbg 专家,但我关注了这篇文章,这篇文章似乎表明大部分内存都被堆堆栈消耗了 (http://hacksoflife.blogspot.co.uk/2009/06/heap-debugging-memoryresource-leak-with.html)
它建议我应该使用一些额外的命令来获取堆栈跟踪,但在获取 dmp 文件(gflags.exe /i yourApplication.exe +ust)之前我没有这样做。
有没有人可以帮助我使用我拥有的 dmp 文件诊断问题?
有人可以验证文章中提到的步骤是否值得遵循以尝试找到此问题?#
有没有人在使用 Stateful Services 之前遇到过这种问题?
附加信息:
这是来自 DotMemory 的检查报告的图像,关于对象泄漏检查我需要重新检查代码我不记得我们在代码中实例化了这些对象。
这是我运行!address -summary得到的输出
0:000> !address -summary
Mapping file section regions...
Mapping module regions...
Mapping PEB regions...
Mapping TEB and stack regions...
Mapping heap regions...
Mapping page heap regions...
Mapping other regions...
Mapping stack trace database regions...
Mapping activation context regions...
--- Usage Summary ---------------- RgnCount ----------- Total Size -------- %ofBusy %ofTotal
Free 865 7ff7`4c03d000 ( 127.966 TB) 99.97%
Heap 85669 6`e0f8e000 ( 27.515 GB) 79.04% 0.02%
<unknown> 21045 1`962b3000 ( 6.346 GB) 18.23% 0.00%
Stack 559 0`2f8c0000 ( 760.750 MB) 2.13% 0.00%
Image 1156 0`0d170000 ( 209.438 MB) 0.59% 0.00%
Other 9 0`001c7000 ( 1.777 MB) 0.00% 0.00%
TEB 189 0`0017a000 ( 1.477 MB) 0.00% 0.00%
PEB 1 0`00001000 ( 4.000 kB) 0.00% 0.00%
--- Type Summary (for busy) ------ RgnCount ----------- Total Size -------- %ofBusy %ofTotal
MEM_PRIVATE 106665 8`a403b000 ( 34.563 GB) 99.28% 0.03%
MEM_IMAGE 1906 0`0ecd1000 ( 236.816 MB) 0.66% 0.00%
MEM_MAPPED 57 0`012a7000 ( 18.652 MB) 0.05% 0.00%
--- State Summary ---------------- RgnCount ----------- Total Size -------- %ofBusy %ofTotal
MEM_FREE 865 7ff7`4c03d000 ( 127.966 TB) 99.97%
MEM_COMMIT 96056 7`718c6000 ( 29.774 GB) 85.53% 0.02%
MEM_RESERVE 12572 1`426ed000 ( 5.038 GB) 14.47% 0.00%
--- Protect Summary (for commit) - RgnCount ----------- Total Size -------- %ofBusy %ofTotal
PAGE_READWRITE 53162 7`56794000 ( 29.351 GB) 84.31% 0.02%
PAGE_NOACCESS 41097 0`0a089000 ( 160.535 MB) 0.45% 0.00%
PAGE_EXECUTE_READ 120 0`08948000 ( 137.281 MB) 0.39% 0.00%
PAGE_READONLY 760 0`05996000 ( 89.586 MB) 0.25% 0.00%
PAGE_EXECUTE_READWRITE 423 0`01a3f000 ( 26.246 MB) 0.07% 0.00%
PAGE_WRITECOPY 259 0`00f4c000 ( 15.297 MB) 0.04% 0.00%
PAGE_READWRITE|PAGE_GUARD 185 0`0033b000 ( 3.230 MB) 0.01% 0.00%
PAGE_EXECUTE_WRITECOPY 50 0`00105000 ( 1.020 MB) 0.00% 0.00%
--- Largest Region by Usage ----------- Base Address -------- Region Size ----------
Free 27e`d5230000 7d77`29c10000 ( 125.465 TB)
Heap 276`50c95000 0`00d3a000 ( 13.227 MB)
<unknown> 275`81a2d000 0`1e5d3000 ( 485.824 MB)
Stack 14c`1f200000 0`00800000 ( 8.000 MB)
Image 7ffc`5d014000 0`01083000 ( 16.512 MB)
Other 275`bf920000 0`00181000 ( 1.504 MB)
TEB f9`09a04000 0`00002000 ( 8.000 kB)
PEB f9`09bf0000 0`00001000 ( 4.000 kB)
这是我从!heap -s得到的输出
0:000> !heap -s
************************************************************************************************************************
NT HEAP STATS BELOW
************************************************************************************************************************
LFH Key : 0x8b79585e7994c063
Termination on corruption : ENABLED
Heap Flags Reserv Commit Virt Free List UCR Virt Lock Fast
(k) (k) (k) (k) length blocks cont. heap
-------------------------------------------------------------------------------------
00000275bf510000 00000002 28701700 28609240 28701500 189846 42173 1804 5 2456d24 LFH
Lock contention 38104356
00000275bf3b0000 00008000 64 4 64 2 1 1 0 0
00000275bf780000 00001002 1280 368 1080 100 8 2 0 0 LFH
00000275bf710000 00001002 1280 388 1080 109 7 2 0 0 LFH
00000275bfc80000 00001002 1280 264 1080 7 9 2 0 0 LFH
00000275bfe70000 00041002 60 8 60 5 1 1 0 0
00000275d8730000 00041002 260 68 60 14 2 1 0 0 LFH
00000275d89a0000 00001002 31792 15028 31592 3404 244 14 3 106 LFH
External fragmentation 22 % (244 free blocks)
00000275d8950000 00001002 80356 19512 80156 17801 91 36 0 22 LFH
External fragmentation 91 % (91 free blocks)
00000275d8930000 00001002 1280 104 1080 29 4 2 0 0 LFH
00000275b2610000 00001002 1280 532 1080 62 15 2 0 1 LFH
00000275b0be0000 00001002 1280 88 1080 15 4 2 0 1 LFH
00000275b2840000 00001002 1280 556 1080 48 16 2 0 1 LFH
00000275b2bc0000 00001002 1280 92 1080 18 5 2 0 0 LFH
2017 年 7 月 12 日更新:
使用来自!heap -flt s 228的输出
我们发现了一个包含 0000 的堆,其条目类型如下:
0000027d680d8d60 0023 0023 [00] 0000027d680d8d70 00228 - (busy)
? FabricClient!GetFabricClientDefaultSettings+4ba320
这导致我们看一下我们的 BaseActor 类,在该类中,我们使用 Lazy<T> 在结构中创建了一个 FabricClient 实例,但从不丢弃它,因此我目前正在调查对 FabricClient 实例的正确处理演员一生。
【问题讨论】:
-
内存分配是否随着您添加到状态管理器的每个项目而增长?您确定这是一个实际问题吗?
-
恕我直言,步骤没问题。您可以控制本机代码吗?你能改变那个代码的实现还是改变你使用它的方式?它也可能是您的 .NET 代码中的错误。也许你应该处理一些东西。由于您已经拥有(并且可能知道如何使用)dotMemory,我将首先查找 .NET 对象泄漏,然后检查该泄漏是否与本机泄漏有关
-
嘿@LoekD - 你提出了一个很好的问题,我们之前有过这样的事情,我们与 SF 团队进行了交谈,似乎有固定(和大量)数量的空条目添加到字典。所以我的问题可能变成了,我如何阻止 Actor Service 要求比服务器更多的资源?演员的生命周期都是默认的。
-
我们在此服务中知道的唯一本机代码来自 ServiceFabric SDK,尽管我们完全有可能在 .NET 代码中存在导致它未被处理的错误。我们看了很多次,还没有找到任何东西。
-
第一张图片展示了什么样的记忆?使用了哪个工具?它是否显示物理 RAM、虚拟内存、全局或特定于进程,...?该本机内存是保留还是提交(尝试
!address -summary)?
标签: memory-leaks windbg azure-service-fabric heap-memory stateful-actor-service