终结器线程 ID
Finalizer Thread Id
我们发现我们的一个 WCF 应用程序存在内存泄漏,我想知道是否有人可以为我澄清一些事情。使用 windbg I 运行 !finalizequeue,它显示每个堆中的数千个对象设置为 "Ready for finalization"。
Heap 0
generation 0 has 464 finalizable objects (0000000033877190->0000000033878010)
generation 1 has 52 finalizable objects (0000000033876ff0->0000000033877190)
generation 2 has 19958 finalizable objects (0000000033850040->0000000033876ff0)
Ready for finalization 228791 objects (0000000033878010->0000000033a36dc8)
------------------------------
Heap 1
generation 0 has 1508 finalizable objects (000000002ee2e168->000000002ee31088)
generation 1 has 91 finalizable objects (000000002ee2de90->000000002ee2e168)
generation 2 has 23498 finalizable objects (000000002ee00040->000000002ee2de90)
Ready for finalization 249421 objects (000000002ee31088->000000002f0182f0)
------------------------------
Heap 2
generation 0 has 66 finalizable objects (00000000292660d0->00000000292662e0)
generation 1 has 63 finalizable objects (0000000029265ed8->00000000292660d0)
generation 2 has 19411 finalizable objects (0000000029240040->0000000029265ed8)
Ready for finalization 238531 objects (00000000292662e0->00000000294380f8)
------------------------------
Heap 3
generation 0 has 510 finalizable objects (0000000034e470d8->0000000034e480c8)
generation 1 has 77 finalizable objects (0000000034e46e70->0000000034e470d8)
generation 2 has 19910 finalizable objects (0000000034e20040->0000000034e46e70)
Ready for finalization 226933 objects (0000000034e480c8->0000000035003470)
Statistics for all finalizable objects (including all objects ready for finalization):
这告诉我终结器线程卡住了。所以我 运行 windbg 中的 !Threads 命令获取终结器线程 ID,这就是它显示的内容....
ThreadCount: 2969
UnstartedThread: 0
BackgroundThread: 187
PendingThread: 0
DeadThread: 2782
Hosted Runtime: no
Lock
ID OSID ThreadOBJ State GC Mode GC Alloc Context Domain Count Apt Exception
XXXX 2 19e8 0000000001f64b10 80039220 Preemptive 0000000000000000:0000000000000000 000000000d4aacb0 0 Ukn (Finalizer)
18 3 cb4 000000000d9bf7a0 102a220 Preemptive 0000000000000000:0000000000000000 000000000150e940 0 MTA (Threadpool Worker)
19 4 1a24 000000000f762720 21220 Preemptive 0000000000000000:0000000000000000 000000000150e940 0 Ukn
20 6 e1c 0000000010f4eae0 3029220 Preemptive 0000000000000000:0000000000000000 000000000d4aacb0 0 MTA (Threadpool Worker)
22 48 1548 000000001feb1880 21220 Preemptive 0000000000000000:0000000000000000 000000000150e940 0 Ukn
23 49 11a4 000000001feb2050 21220 Preemptive 0000000000000000:0000000000000000 000000000150e940 0 Ukn
24 50 a64 000000001feb2820 21220 Preemptive 0000000000000000:0000000000000000 000000000150e940 0 Ukn
列表中的第一个线程是终结器线程,线程 ID 是 XXXX。那是什么意思?我猜这意味着线程不再存在,或者不是 运行。有人可以确认或纠正我的理解吗?
更新
我 运行 ~2s;kb 命令,如评论中建议的 Kjell Gunnar,这是输出。
0:028> ~2s;kb
ntdll!ZwRemoveIoCompletion+0xa:
00000000`77c1bdca c3 ret
RetAddr : Args to Child : Call Site
000007fe`fe0e16ad : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : ntdll!ZwRemoveIoCompletion+0xa
00000000`776f9991 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : KERNELBASE!GetQueuedCompletionStatus+0x39
000007fe`fb7f6bb1 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : kernel32!GetQueuedCompletionStatusStub+0x11
00000000`777059cd : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : nativerd!NOTIFICATION_THREAD::ThreadProc+0x71
00000000`77bfa561 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : kernel32!BaseThreadInitThunk+0xd
00000000`00000000 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : ntdll!RtlUserThreadStart+0x1d
ZwRemoveIoCompletion 是什么意思?
您看到的前三列是
- WinDbg 线程 ID。你可以例如在
~xs
命令中使用它,其中 x
是线程的 ID。
- CLR 线程 ID,它与 .NET 堆上的
Thread
个对象相关(尝试 !dumpheap -type Thread
,然后在线程对象上 !do
,查看 m_ManagedThreadId
).我从未找到真正的用例。
- 内核线程 ID,也由许多其他工具显示,例如任务管理器或进程资源管理器
有一些特殊情况,您似乎 运行 属于其中之一。如果第一列显示 XXXX
,.NET 没有分配固定物理 OS 线程。对于由 .NET 运行时管理的线程,例如来自线程池的线程。在某个时间点,它可能会再次获得物理线程。
此外,似乎有些情况下 .NET 仍然记得 OS 线程(以下示例的第一行,OS ID f28
),而当它不记得时(第二、三行,其中OS ID为0
):
XXXX 3 f28 00000087c5f974c0 80030228 Preemptive 00000087C6033180:00000087C6033FD0 00000087c4213450 0 Ukn
XXXX 4 0 00000087c5fa24b0 39820 Preemptive 0000000000000000:0000000000000000 00000087c4213450 0 MTA
XXXX 5 0 00000087c5fd0eb0 39820 Preemptive 0000000000000000:0000000000000000 00000087c4213450 0 MTA
通常 OS 线程 ID 很有用,因为它与 ~
的输出相关(1098
是进程 ID)。但是,在我的转储文件中,没有 ID 为 f28
:
的本机线程
0:009> ~
0 Id: 1098.564 Suspend: 0 Teb: 000007f5`ffd3d000 Unfrozen
1 Id: 1098.1e98 Suspend: 0 Teb: 000007f5`ffd3b000 Unfrozen
2 Id: 1098.1d6c Suspend: 0 Teb: 000007f5`ffd39000 Unfrozen
3 Id: 1098.458 Suspend: 0 Teb: 000007f5`ffd35000 Unfrozen
4 Id: 1098.13d4 Suspend: 0 Teb: 000007f5`ffd33000 Unfrozen
5 Id: 1098.1b20 Suspend: 0 Teb: 000007f5`ffb5e000 Unfrozen
6 Id: 1098.80c Suspend: 0 Teb: 000007f5`ffb52000 Unfrozen
7 Id: 1098.944 Suspend: 0 Teb: 000007f5`ffb5c000 Unfrozen
8 Id: 1098.90 Suspend: 0 Teb: 000007f5`ffb5a000 Unfrozen
. 9 Id: 1098.1738 Suspend: 0 Teb: 000007f5`ffb58000 Unfrozen
您可以检查的一件事是线程状态,在您的情况下报告为 80039220
。这给了我们:
0:009> !ThreadState 80039220
Legal to Join
Background
CLR Owns
In Multi Threaded Apartment
Reported Dead
Fully initialized
Detached
Reported dead
似乎印证了你的悲伤
我们发现我们的一个 WCF 应用程序存在内存泄漏,我想知道是否有人可以为我澄清一些事情。使用 windbg I 运行 !finalizequeue,它显示每个堆中的数千个对象设置为 "Ready for finalization"。
Heap 0
generation 0 has 464 finalizable objects (0000000033877190->0000000033878010)
generation 1 has 52 finalizable objects (0000000033876ff0->0000000033877190)
generation 2 has 19958 finalizable objects (0000000033850040->0000000033876ff0)
Ready for finalization 228791 objects (0000000033878010->0000000033a36dc8)
------------------------------
Heap 1
generation 0 has 1508 finalizable objects (000000002ee2e168->000000002ee31088)
generation 1 has 91 finalizable objects (000000002ee2de90->000000002ee2e168)
generation 2 has 23498 finalizable objects (000000002ee00040->000000002ee2de90)
Ready for finalization 249421 objects (000000002ee31088->000000002f0182f0)
------------------------------
Heap 2
generation 0 has 66 finalizable objects (00000000292660d0->00000000292662e0)
generation 1 has 63 finalizable objects (0000000029265ed8->00000000292660d0)
generation 2 has 19411 finalizable objects (0000000029240040->0000000029265ed8)
Ready for finalization 238531 objects (00000000292662e0->00000000294380f8)
------------------------------
Heap 3
generation 0 has 510 finalizable objects (0000000034e470d8->0000000034e480c8)
generation 1 has 77 finalizable objects (0000000034e46e70->0000000034e470d8)
generation 2 has 19910 finalizable objects (0000000034e20040->0000000034e46e70)
Ready for finalization 226933 objects (0000000034e480c8->0000000035003470)
Statistics for all finalizable objects (including all objects ready for finalization):
这告诉我终结器线程卡住了。所以我 运行 windbg 中的 !Threads 命令获取终结器线程 ID,这就是它显示的内容....
ThreadCount: 2969
UnstartedThread: 0
BackgroundThread: 187
PendingThread: 0
DeadThread: 2782
Hosted Runtime: no
Lock
ID OSID ThreadOBJ State GC Mode GC Alloc Context Domain Count Apt Exception
XXXX 2 19e8 0000000001f64b10 80039220 Preemptive 0000000000000000:0000000000000000 000000000d4aacb0 0 Ukn (Finalizer)
18 3 cb4 000000000d9bf7a0 102a220 Preemptive 0000000000000000:0000000000000000 000000000150e940 0 MTA (Threadpool Worker)
19 4 1a24 000000000f762720 21220 Preemptive 0000000000000000:0000000000000000 000000000150e940 0 Ukn
20 6 e1c 0000000010f4eae0 3029220 Preemptive 0000000000000000:0000000000000000 000000000d4aacb0 0 MTA (Threadpool Worker)
22 48 1548 000000001feb1880 21220 Preemptive 0000000000000000:0000000000000000 000000000150e940 0 Ukn
23 49 11a4 000000001feb2050 21220 Preemptive 0000000000000000:0000000000000000 000000000150e940 0 Ukn
24 50 a64 000000001feb2820 21220 Preemptive 0000000000000000:0000000000000000 000000000150e940 0 Ukn
列表中的第一个线程是终结器线程,线程 ID 是 XXXX。那是什么意思?我猜这意味着线程不再存在,或者不是 运行。有人可以确认或纠正我的理解吗?
更新
我 运行 ~2s;kb 命令,如评论中建议的 Kjell Gunnar,这是输出。
0:028> ~2s;kb
ntdll!ZwRemoveIoCompletion+0xa:
00000000`77c1bdca c3 ret
RetAddr : Args to Child : Call Site
000007fe`fe0e16ad : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : ntdll!ZwRemoveIoCompletion+0xa
00000000`776f9991 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : KERNELBASE!GetQueuedCompletionStatus+0x39
000007fe`fb7f6bb1 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : kernel32!GetQueuedCompletionStatusStub+0x11
00000000`777059cd : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : nativerd!NOTIFICATION_THREAD::ThreadProc+0x71
00000000`77bfa561 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : kernel32!BaseThreadInitThunk+0xd
00000000`00000000 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : ntdll!RtlUserThreadStart+0x1d
ZwRemoveIoCompletion 是什么意思?
您看到的前三列是
- WinDbg 线程 ID。你可以例如在
~xs
命令中使用它,其中x
是线程的 ID。 - CLR 线程 ID,它与 .NET 堆上的
Thread
个对象相关(尝试!dumpheap -type Thread
,然后在线程对象上!do
,查看m_ManagedThreadId
).我从未找到真正的用例。 - 内核线程 ID,也由许多其他工具显示,例如任务管理器或进程资源管理器
有一些特殊情况,您似乎 运行 属于其中之一。如果第一列显示 XXXX
,.NET 没有分配固定物理 OS 线程。对于由 .NET 运行时管理的线程,例如来自线程池的线程。在某个时间点,它可能会再次获得物理线程。
此外,似乎有些情况下 .NET 仍然记得 OS 线程(以下示例的第一行,OS ID f28
),而当它不记得时(第二、三行,其中OS ID为0
):
XXXX 3 f28 00000087c5f974c0 80030228 Preemptive 00000087C6033180:00000087C6033FD0 00000087c4213450 0 Ukn
XXXX 4 0 00000087c5fa24b0 39820 Preemptive 0000000000000000:0000000000000000 00000087c4213450 0 MTA
XXXX 5 0 00000087c5fd0eb0 39820 Preemptive 0000000000000000:0000000000000000 00000087c4213450 0 MTA
通常 OS 线程 ID 很有用,因为它与 ~
的输出相关(1098
是进程 ID)。但是,在我的转储文件中,没有 ID 为 f28
:
0:009> ~
0 Id: 1098.564 Suspend: 0 Teb: 000007f5`ffd3d000 Unfrozen
1 Id: 1098.1e98 Suspend: 0 Teb: 000007f5`ffd3b000 Unfrozen
2 Id: 1098.1d6c Suspend: 0 Teb: 000007f5`ffd39000 Unfrozen
3 Id: 1098.458 Suspend: 0 Teb: 000007f5`ffd35000 Unfrozen
4 Id: 1098.13d4 Suspend: 0 Teb: 000007f5`ffd33000 Unfrozen
5 Id: 1098.1b20 Suspend: 0 Teb: 000007f5`ffb5e000 Unfrozen
6 Id: 1098.80c Suspend: 0 Teb: 000007f5`ffb52000 Unfrozen
7 Id: 1098.944 Suspend: 0 Teb: 000007f5`ffb5c000 Unfrozen
8 Id: 1098.90 Suspend: 0 Teb: 000007f5`ffb5a000 Unfrozen
. 9 Id: 1098.1738 Suspend: 0 Teb: 000007f5`ffb58000 Unfrozen
您可以检查的一件事是线程状态,在您的情况下报告为 80039220
。这给了我们:
0:009> !ThreadState 80039220
Legal to Join
Background
CLR Owns
In Multi Threaded Apartment
Reported Dead
Fully initialized
Detached
Reported dead
似乎印证了你的悲伤