【发布时间】:2018-07-22 19:40:39
【问题描述】:
我正在处理来自客户的核心转储。因此,我将无法共享导致错误的代码片段。不过,我希望有人能对如何进一步进行一些提示。
我有一个通过套接字执行通信的应用程序。它打开到多个客户端的连接数。一段时间后,它失败并出现 OutOfMemoryException,即使服务器上有足够的内存并且进程没有超过 32 位的限制。
核心转储中的线程池状态如下所示:
!ThreadPool
CPU utilization: 17%
Worker Thread: Total: 16 Running: 0 Idle: 16 MaxLimit: 1023 MinLimit: 16
Work Request in Queue: 0
--------------------------------------
Number of Timers: 2
--------------------------------------
Completion Port Thread:Total: 29 Free: 0 MaxFree: 32 CurrentLimit: 29
MaxLimit: 1000 MinLimit: 16
29 个完成端口线程中的大多数都会抛出 OutOfMemoryException。
!Threads 输出的一部分如下所示:
0 1 1c548 00390680 2026020 Preemptive 00000000:00000000 0038a7f0 0 STA
2 2 2b770 0039db70 2b220 Preemptive 00000000:00000000 0038a7f0 0 MTA (Finalizer)
6 3 2c080 003ef588 a029220 Preemptive 00000000:00000000 0038a7f0 0 MTA (Threadpool Completion Port)
7 4 22ae4 004067e0 202b020 Preemptive 0F0905F0:00000000 0038a7f0 0 MTA
11 5 1ba94 03a79358 a029220 Preemptive 00000000:00000000 03a99928 0 MTA (Threadpool Completion Port)
12 6 3105c 03a7c138 a029220 Preemptive 00000000:00000000 03a99928 0 MTA (Threadpool Completion Port) System.OutOfMemoryException 016c4bc8
13 7 250f0 03a7c958 a029220 Preemptive 0F5B50BC:00000000 03a99928 0 MTA (Threadpool Completion Port) System.OutOfMemoryException 00ef70fc
14 8 32d9c 03a7d578 a029220 Preemptive 00000000:00000000 03a99928 0 MTA (Threadpool Completion Port) System.OutOfMemoryException 016c896c
15 9 3281c 03a7dd98 a029220 Preemptive 00000000:00000000 03a99928 0 MTA (Threadpool Completion Port) System.OutOfMemoryException 016c2f2c
16 10 1c360 03a7e7c0 a029220 Preemptive 00000000:00000000 03a99928 0 MTA (Threadpool Completion Port) System.OutOfMemoryException 016bc434
17 11 240ac 03a815f0 a029220 Preemptive 00000000:00000000 03a99928 0 MTA (Threadpool Completion Port) System.OutOfMemoryException 016bb198
18 12 250fc 03a8fcd0 21220 Preemptive 00000000:00000000 0038a7f0 0 Ukn
19 13 30f1c 03ab4fb0 102a220 Preemptive 00000000:00000000 0038a7f0 0 MTA (Threadpool Worker)
20 14 1a034 03ae9210 202b020 Preemptive 0F625BB8:00000000 03a99928 0 MTA
21 15 1f3bc 03ae49b8 202b220 Preemptive 00000000:00000000 03a99928 1 MTA
22 16 f8d8 03aba8c8 202b020 Preemptive 00000000:00000000 03a99928 0 MTA
23 17 32808 03b10118 a029220 Preemptive 00000000:00000000 03a99928 0 MTA (Threadpool Completion Port) System.OutOfMemoryException 016bb760
24 18 2ee1c 03b0fbd0 a029220 Preemptive 00000000:00000000 03a99928 0 MTA (Threadpool Completion Port) System.OutOfMemoryException 016bc268
25 19 539c 03b0ebf8 a029220 Preemptive 00000000:00000000 03a99928 0 MTA (Threadpool Completion Port) System.OutOfMemoryException 016c6288
26 20 31be8 03b0f140 202b220 Preemptive 00000000:00000000 03a99928 1 MTA
27 21 2e884 03b10660 202b220 Preemptive 00000000:00000000 03a99928 1 MTA
28 22 10934 03b0f688 202b220 Preemptive 00000000:00000000 03a99928 1 MTA
对我来说,这看起来像是一个死锁,消费者停止处理传入套接字的数据,但这只是一个模糊的理论。
你对此有什么想法吗?
【问题讨论】:
-
另外,显然,首先对失败的线程进行堆栈跟踪。有可能一个通用的“资源不足”或“无效参数”错误代码被转换为“内存不足”,即使 memory 实际上并不是我们用完的资源(但是例如,某个地方的内核池的一小部分,或固定的句柄缓冲区,或
OVERLAPPED池,或设计者想出的其他任何东西)。找到失败的呼叫将对此有所帮助。 -
一个好的开始是运行
!dumpheap -stat并查看托管内存使用了多少总空间,包括可用空间。最后一点很重要,因为它可以帮助您评估在碎片中丢失了多少内存空间(如果应用程序执行大量 LOH 分配,这可能是一个问题)
标签: c# .net multithreading sockets